Skip to content

Commit 005d1d3

Browse files
authored
[derive] Don't support IntoBytes on repr(Rust) types (google#1783)
Closes google#1764
1 parent b0a8477 commit 005d1d3

File tree

6 files changed

+167
-112
lines changed

6 files changed

+167
-112
lines changed

zerocopy-derive/src/lib.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -769,12 +769,11 @@ fn derive_into_bytes_struct(ast: &DeriveInput, strct: &DataStruct) -> Result<Tok
769769
// no padding unless #[repr(align)] explicitly adds padding, which we
770770
// check for in this branch's condition.
771771
(None, false)
772-
} else if ast.generics.params.is_empty() {
773-
// Since there are no generics, we can emit a padding check. This is
774-
// more permissive than the next case, which requires that all field
775-
// types implement `Unaligned`.
776-
//
777-
// TODO(#1764): This is probably unsound! Fix it.
772+
} else if is_c && ast.generics.params.is_empty() {
773+
// Since there are no generics, we can emit a padding check. `repr(C)`
774+
// guarantees that fields won't overlap, so the padding check is sound.
775+
// This is more permissive than the next case, which requires that all
776+
// field types implement `Unaligned`.
778777
(Some(PaddingCheck::Struct), false)
779778
} else if is_c && !repr.is_align_gt_1() {
780779
// We can't use a padding check since there are generic type arguments.
@@ -787,7 +786,7 @@ fn derive_into_bytes_struct(ast: &DeriveInput, strct: &DataStruct) -> Result<Tok
787786
// structs without requiring `Unaligned`.
788787
(None, true)
789788
} else {
790-
return Err(Error::new(Span::call_site(), "must have a non-align #[repr(...)] attribute or #[repr(packed)] in order to guarantee this type's memory layout"));
789+
return Err(Error::new(Span::call_site(), "must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout"));
791790
};
792791

793792
let field_bounds = if require_unaligned_fields {

zerocopy-derive/tests/struct_to_bytes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::IntoBytes);
153153
// Test for the failure reported in #1182.
154154

155155
#[derive(imp::IntoBytes)]
156-
#[repr(packed)]
156+
#[repr(C, packed)]
157157
pub struct IndexEntryFlags(u8);
158158

159159
#[derive(imp::IntoBytes)]

zerocopy-derive/tests/ui-msrv/struct.stderr

+44-28
Original file line numberDiff line numberDiff line change
@@ -4,94 +4,110 @@ error: this conflicts with another representation hint
44
133 | #[repr(C, C)] // zerocopy-derive conservatively treats these as conflicting reprs
55
| ^
66

7-
error: must have a non-align #[repr(...)] attribute or #[repr(packed)] in order to guarantee this type's memory layout
8-
--> tests/ui-msrv/struct.rs:151:10
7+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
8+
--> tests/ui-msrv/struct.rs:140:10
99
|
10-
151 | #[derive(IntoBytes)]
10+
140 | #[derive(IntoBytes)]
1111
| ^^^^^^^^^
1212
|
1313
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
1414

15-
error: must have a non-align #[repr(...)] attribute or #[repr(packed)] in order to guarantee this type's memory layout
16-
--> tests/ui-msrv/struct.rs:156:10
15+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
16+
--> tests/ui-msrv/struct.rs:150:10
1717
|
18-
156 | #[derive(IntoBytes)]
18+
150 | #[derive(IntoBytes)]
1919
| ^^^^^^^^^
2020
|
2121
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
2222

23-
error: must have a non-align #[repr(...)] attribute or #[repr(packed)] in order to guarantee this type's memory layout
23+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
24+
--> tests/ui-msrv/struct.rs:159:10
25+
|
26+
159 | #[derive(IntoBytes)]
27+
| ^^^^^^^^^
28+
|
29+
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
30+
31+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
2432
--> tests/ui-msrv/struct.rs:164:10
2533
|
2634
164 | #[derive(IntoBytes)]
2735
| ^^^^^^^^^
2836
|
2937
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
3038

31-
error: must have a non-align #[repr(...)] attribute or #[repr(packed)] in order to guarantee this type's memory layout
32-
--> tests/ui-msrv/struct.rs:187:10
39+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
40+
--> tests/ui-msrv/struct.rs:172:10
41+
|
42+
172 | #[derive(IntoBytes)]
43+
| ^^^^^^^^^
44+
|
45+
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
46+
47+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
48+
--> tests/ui-msrv/struct.rs:195:10
3349
|
34-
187 | #[derive(IntoBytes)]
50+
195 | #[derive(IntoBytes)]
3551
| ^^^^^^^^^
3652
|
3753
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
3854

3955
error: cannot derive `Unaligned` on type with alignment greater than 1
40-
--> tests/ui-msrv/struct.rs:198:11
56+
--> tests/ui-msrv/struct.rs:206:11
4157
|
42-
198 | #[repr(C, align(2))]
58+
206 | #[repr(C, align(2))]
4359
| ^^^^^
4460

4561
error: this conflicts with another representation hint
46-
--> tests/ui-msrv/struct.rs:202:8
62+
--> tests/ui-msrv/struct.rs:210:8
4763
|
48-
202 | #[repr(transparent, align(2))]
64+
210 | #[repr(transparent, align(2))]
4965
| ^^^^^^^^^^^
5066

5167
error: this conflicts with another representation hint
52-
--> tests/ui-msrv/struct.rs:208:16
68+
--> tests/ui-msrv/struct.rs:216:16
5369
|
54-
208 | #[repr(packed, align(2))]
70+
216 | #[repr(packed, align(2))]
5571
| ^^^^^
5672

5773
error: this conflicts with another representation hint
58-
--> tests/ui-msrv/struct.rs:212:18
74+
--> tests/ui-msrv/struct.rs:220:18
5975
|
60-
212 | #[repr(align(1), align(2))]
76+
220 | #[repr(align(1), align(2))]
6177
| ^^^^^
6278

6379
error: this conflicts with another representation hint
64-
--> tests/ui-msrv/struct.rs:216:18
80+
--> tests/ui-msrv/struct.rs:224:18
6581
|
66-
216 | #[repr(align(2), align(4))]
82+
224 | #[repr(align(2), align(4))]
6783
| ^^^^^
6884

6985
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
70-
--> tests/ui-msrv/struct.rs:219:10
86+
--> tests/ui-msrv/struct.rs:227:10
7187
|
72-
219 | #[derive(Unaligned)]
88+
227 | #[derive(Unaligned)]
7389
| ^^^^^^^^^
7490
|
7591
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
7692

7793
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
78-
--> tests/ui-msrv/struct.rs:222:10
94+
--> tests/ui-msrv/struct.rs:230:10
7995
|
80-
222 | #[derive(Unaligned)]
96+
230 | #[derive(Unaligned)]
8197
| ^^^^^^^^^
8298
|
8399
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
84100

85101
error: this conflicts with another representation hint
86-
--> tests/ui-msrv/struct.rs:232:8
102+
--> tests/ui-msrv/struct.rs:240:8
87103
|
88-
232 | #[repr(C, packed(2))]
104+
240 | #[repr(C, packed(2))]
89105
| ^
90106

91107
error[E0692]: transparent struct cannot have other repr hints
92-
--> tests/ui-msrv/struct.rs:202:8
108+
--> tests/ui-msrv/struct.rs:210:8
93109
|
94-
202 | #[repr(transparent, align(2))]
110+
210 | #[repr(transparent, align(2))]
95111
| ^^^^^^^^^^^ ^^^^^^^^
96112

97113
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time

zerocopy-derive/tests/ui-nightly/struct.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -135,17 +135,25 @@ struct IntoBytes5 {
135135
a: u8,
136136
}
137137

138-
// TODO(#1764): This currently compiles, but maybe it shouldn't.
138+
// We don't emit a padding check unless there's a repr that can guarantee that
139+
// fields don't overlap.
139140
#[derive(IntoBytes)]
140141
struct IntoBytes6 {
141142
a: u8,
143+
// Add a second field to avoid triggering the "repr(C) struct with one
144+
// field" special case.
145+
b: u8,
142146
}
143147

144-
// TODO(#1764): This currently compiles, but maybe it shouldn't.
148+
// We don't emit a padding check unless there's a repr that can guarantee that
149+
// fields don't overlap. `repr(packed)` on its own doesn't guarantee this.
145150
#[derive(IntoBytes)]
146151
#[repr(packed(2))]
147152
struct IntoBytes7 {
148153
a: u8,
154+
// Add a second field to avoid triggering the "repr(C) struct with one
155+
// field" special case.
156+
b: u8,
149157
}
150158

151159
#[derive(IntoBytes)]

zerocopy-derive/tests/ui-nightly/struct.stderr

+54-38
Original file line numberDiff line numberDiff line change
@@ -4,97 +4,113 @@ error: this conflicts with another representation hint
44
133 | #[repr(C, C)] // zerocopy-derive conservatively treats these as conflicting reprs
55
| ^^^^
66

7-
error: must have a non-align #[repr(...)] attribute or #[repr(packed)] in order to guarantee this type's memory layout
8-
--> tests/ui-nightly/struct.rs:151:10
7+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
8+
--> tests/ui-nightly/struct.rs:140:10
99
|
10-
151 | #[derive(IntoBytes)]
10+
140 | #[derive(IntoBytes)]
1111
| ^^^^^^^^^
1212
|
1313
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
1414

15-
error: must have a non-align #[repr(...)] attribute or #[repr(packed)] in order to guarantee this type's memory layout
16-
--> tests/ui-nightly/struct.rs:156:10
15+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
16+
--> tests/ui-nightly/struct.rs:150:10
1717
|
18-
156 | #[derive(IntoBytes)]
18+
150 | #[derive(IntoBytes)]
1919
| ^^^^^^^^^
2020
|
2121
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
2222

23-
error: must have a non-align #[repr(...)] attribute or #[repr(packed)] in order to guarantee this type's memory layout
23+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
24+
--> tests/ui-nightly/struct.rs:159:10
25+
|
26+
159 | #[derive(IntoBytes)]
27+
| ^^^^^^^^^
28+
|
29+
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
30+
31+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
2432
--> tests/ui-nightly/struct.rs:164:10
2533
|
2634
164 | #[derive(IntoBytes)]
2735
| ^^^^^^^^^
2836
|
2937
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
3038

31-
error: must have a non-align #[repr(...)] attribute or #[repr(packed)] in order to guarantee this type's memory layout
32-
--> tests/ui-nightly/struct.rs:187:10
39+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
40+
--> tests/ui-nightly/struct.rs:172:10
41+
|
42+
172 | #[derive(IntoBytes)]
43+
| ^^^^^^^^^
44+
|
45+
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
46+
47+
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
48+
--> tests/ui-nightly/struct.rs:195:10
3349
|
34-
187 | #[derive(IntoBytes)]
50+
195 | #[derive(IntoBytes)]
3551
| ^^^^^^^^^
3652
|
3753
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
3854

3955
error: cannot derive `Unaligned` on type with alignment greater than 1
40-
--> tests/ui-nightly/struct.rs:198:11
56+
--> tests/ui-nightly/struct.rs:206:11
4157
|
42-
198 | #[repr(C, align(2))]
58+
206 | #[repr(C, align(2))]
4359
| ^^^^^^^^
4460

4561
error: this conflicts with another representation hint
46-
--> tests/ui-nightly/struct.rs:202:8
62+
--> tests/ui-nightly/struct.rs:210:8
4763
|
48-
202 | #[repr(transparent, align(2))]
64+
210 | #[repr(transparent, align(2))]
4965
| ^^^^^^^^^^^
5066

5167
error: this conflicts with another representation hint
52-
--> tests/ui-nightly/struct.rs:208:8
68+
--> tests/ui-nightly/struct.rs:216:8
5369
|
54-
208 | #[repr(packed, align(2))]
70+
216 | #[repr(packed, align(2))]
5571
| ^^^^^^^^^^^^^^^^
5672

5773
error: this conflicts with another representation hint
58-
--> tests/ui-nightly/struct.rs:212:8
74+
--> tests/ui-nightly/struct.rs:220:8
5975
|
60-
212 | #[repr(align(1), align(2))]
76+
220 | #[repr(align(1), align(2))]
6177
| ^^^^^^^^^^^^^^^^^^
6278

6379
error: this conflicts with another representation hint
64-
--> tests/ui-nightly/struct.rs:216:8
80+
--> tests/ui-nightly/struct.rs:224:8
6581
|
66-
216 | #[repr(align(2), align(4))]
82+
224 | #[repr(align(2), align(4))]
6783
| ^^^^^^^^^^^^^^^^^^
6884

6985
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
70-
--> tests/ui-nightly/struct.rs:219:10
86+
--> tests/ui-nightly/struct.rs:227:10
7187
|
72-
219 | #[derive(Unaligned)]
88+
227 | #[derive(Unaligned)]
7389
| ^^^^^^^^^
7490
|
7591
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
7692

7793
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
78-
--> tests/ui-nightly/struct.rs:222:10
94+
--> tests/ui-nightly/struct.rs:230:10
7995
|
80-
222 | #[derive(Unaligned)]
96+
230 | #[derive(Unaligned)]
8197
| ^^^^^^^^^
8298
|
8399
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
84100

85101
error: this conflicts with another representation hint
86-
--> tests/ui-nightly/struct.rs:230:19
102+
--> tests/ui-nightly/struct.rs:238:19
87103
|
88-
230 | #[repr(packed(2), C)]
104+
238 | #[repr(packed(2), C)]
89105
| ___________________^
90-
231 | | #[derive(Unaligned)]
91-
232 | | #[repr(C, packed(2))]
106+
239 | | #[derive(Unaligned)]
107+
240 | | #[repr(C, packed(2))]
92108
| |________^
93109

94110
error[E0692]: transparent struct cannot have other repr hints
95-
--> tests/ui-nightly/struct.rs:202:8
111+
--> tests/ui-nightly/struct.rs:210:8
96112
|
97-
202 | #[repr(transparent, align(2))]
113+
210 | #[repr(transparent, align(2))]
98114
| ^^^^^^^^^^^ ^^^^^^^^
99115

100116
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
@@ -376,15 +392,15 @@ note: required by a bound in `macro_util::__size_of::size_of`
376392
| ^^^^^ required by this bound in `size_of`
377393

378394
error[E0587]: type has conflicting packed and align representation hints
379-
--> tests/ui-nightly/struct.rs:209:1
395+
--> tests/ui-nightly/struct.rs:217:1
380396
|
381-
209 | struct Unaligned3;
397+
217 | struct Unaligned3;
382398
| ^^^^^^^^^^^^^^^^^
383399

384400
error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
385-
--> tests/ui-nightly/struct.rs:182:28
401+
--> tests/ui-nightly/struct.rs:190:28
386402
|
387-
182 | is_into_bytes_11::<IntoBytes11<AU16>>();
403+
190 | is_into_bytes_11::<IntoBytes11<AU16>>();
388404
| ^^^^^^^^^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`, which is required by `IntoBytes11<AU16>: zerocopy::IntoBytes`
389405
|
390406
= note: Consider adding `#[derive(Unaligned)]` to `AU16`
@@ -399,13 +415,13 @@ error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
399415
I16<O>
400416
and $N others
401417
note: required for `IntoBytes11<AU16>` to implement `zerocopy::IntoBytes`
402-
--> tests/ui-nightly/struct.rs:171:10
418+
--> tests/ui-nightly/struct.rs:179:10
403419
|
404-
171 | #[derive(IntoBytes)]
420+
179 | #[derive(IntoBytes)]
405421
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
406422
note: required by a bound in `is_into_bytes_11`
407-
--> tests/ui-nightly/struct.rs:180:24
423+
--> tests/ui-nightly/struct.rs:188:24
408424
|
409-
180 | fn is_into_bytes_11<T: IntoBytes>() {
425+
188 | fn is_into_bytes_11<T: IntoBytes>() {
410426
| ^^^^^^^^^ required by this bound in `is_into_bytes_11`
411427
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)