]>
Commit | Line | Data |
---|---|---|
d9bb1a4e FG |
1 | A struct, enum, or union with the `repr(transparent)` representation hint |
2 | contains a zero-sized field that requires non-trivial alignment. | |
3 | ||
4 | Erroneous code example: | |
5 | ||
6 | ```compile_fail,E0691 | |
7 | #![feature(repr_align)] | |
8 | ||
9 | #[repr(align(32))] | |
10 | struct ForceAlign32; | |
11 | ||
12 | #[repr(transparent)] | |
13 | struct Wrapper(f32, ForceAlign32); // error: zero-sized field in transparent | |
14 | // struct has alignment larger than 1 | |
15 | ``` | |
16 | ||
17 | A transparent struct, enum, or union is supposed to be represented exactly like | |
18 | the piece of data it contains. Zero-sized fields with different alignment | |
19 | requirements potentially conflict with this property. In the example above, | |
20 | `Wrapper` would have to be aligned to 32 bytes even though `f32` has a smaller | |
21 | alignment requirement. | |
22 | ||
23 | Consider removing the over-aligned zero-sized field: | |
24 | ||
25 | ``` | |
26 | #[repr(transparent)] | |
27 | struct Wrapper(f32); | |
28 | ``` | |
29 | ||
30 | Alternatively, `PhantomData<T>` has alignment 1 for all `T`, so you can use it | |
31 | if you need to keep the field for some reason: | |
32 | ||
33 | ``` | |
34 | #![feature(repr_align)] | |
35 | ||
36 | use std::marker::PhantomData; | |
37 | ||
38 | #[repr(align(32))] | |
39 | struct ForceAlign32; | |
40 | ||
41 | #[repr(transparent)] | |
42 | struct Wrapper(f32, PhantomData<ForceAlign32>); | |
43 | ``` | |
44 | ||
45 | Note that empty arrays `[T; 0]` have the same alignment requirement as the | |
46 | element type `T`. Also note that the error is conservatively reported even when | |
47 | the alignment of the zero-sized type is less than or equal to the data field's | |
48 | alignment. |