]> git.lizzy.rs Git - rust.git/blob - src/test/ui/structs-enums/type-sizes.rs
Rollup merge of #105843 - compiler-errors:sugg-const, r=lcnr
[rust.git] / src / test / ui / structs-enums / type-sizes.rs
1 // run-pass
2
3 #![allow(non_camel_case_types)]
4 #![allow(dead_code)]
5 #![feature(never_type)]
6 #![feature(pointer_is_aligned)]
7
8 use std::mem::size_of;
9 use std::num::NonZeroU8;
10
11 struct t {a: u8, b: i8}
12 struct u {a: u8, b: i8, c: u8}
13 struct v {a: u8, b: i8, c: v2, d: u32}
14 struct v2 {u: char, v: u8}
15 struct w {a: isize, b: ()}
16 struct x {a: isize, b: (), c: ()}
17 struct y {x: isize}
18
19 enum e1 {
20     a(u8, u32), b(u32), c
21 }
22 enum e2 {
23     a(u32), b
24 }
25
26 #[repr(C, u8)]
27 enum e3 {
28     a([u16; 0], u8), b
29 }
30
31 struct ReorderedStruct {
32     a: u8,
33     b: u16,
34     c: u8
35 }
36
37 enum ReorderedEnum {
38     A(u8, u16, u8),
39     B(u8, u16, u8),
40 }
41
42 enum ReorderedEnum2 {
43     A(u8, u32, u8),
44     B(u16, u8, u16, u8),
45
46     // 0x100 niche variants.
47     _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, _0A, _0B, _0C, _0D, _0E, _0F,
48     _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _1A, _1B, _1C, _1D, _1E, _1F,
49     _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _2A, _2B, _2C, _2D, _2E, _2F,
50     _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _3A, _3B, _3C, _3D, _3E, _3F,
51     _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _4A, _4B, _4C, _4D, _4E, _4F,
52     _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _5A, _5B, _5C, _5D, _5E, _5F,
53     _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _6A, _6B, _6C, _6D, _6E, _6F,
54     _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _7A, _7B, _7C, _7D, _7E, _7F,
55     _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _8A, _8B, _8C, _8D, _8E, _8F,
56     _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9A, _9B, _9C, _9D, _9E, _9F,
57     _A0, _A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8, _A9, _AA, _AB, _AC, _AD, _AE, _AF,
58     _B0, _B1, _B2, _B3, _B4, _B5, _B6, _B7, _B8, _B9, _BA, _BB, _BC, _BD, _BE, _BF,
59     _C0, _C1, _C2, _C3, _C4, _C5, _C6, _C7, _C8, _C9, _CA, _CB, _CC, _CD, _CE, _CF,
60     _D0, _D1, _D2, _D3, _D4, _D5, _D6, _D7, _D8, _D9, _DA, _DB, _DC, _DD, _DE, _DF,
61     _E0, _E1, _E2, _E3, _E4, _E5, _E6, _E7, _E8, _E9, _EA, _EB, _EC, _ED, _EE, _EF,
62     _F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _FA, _FB, _FC, _FD, _FE, _FF,
63 }
64
65 enum EnumEmpty {}
66
67 enum EnumSingle1 {
68     A,
69 }
70
71 enum EnumSingle2 {
72     A = 42 as isize,
73 }
74
75 enum EnumSingle3 {
76     A,
77     B(!),
78 }
79
80 #[repr(u8)]
81 enum EnumSingle4 {
82     A,
83 }
84
85 #[repr(u8)]
86 enum EnumSingle5 {
87     A = 42 as u8,
88 }
89
90 enum EnumWithMaybeUninhabitedVariant<T> {
91     A(&'static ()),
92     B(&'static (), T),
93     C,
94 }
95
96 enum NicheFilledEnumWithAbsentVariant {
97     A(&'static ()),
98     B((), !),
99     C,
100 }
101
102 enum Option2<A, B> {
103     Some(A, B),
104     None
105 }
106
107 // Two layouts are considered for `CanBeNicheFilledButShouldnt`:
108 //   Niche-filling:
109 //     { u32 (4 bytes), NonZeroU8 + tag in niche (1 byte), padding (3 bytes) }
110 //   Tagged:
111 //     { tag (1 byte), NonZeroU8 (1 byte), padding (2 bytes), u32 (4 bytes) }
112 // Both are the same size (due to padding),
113 // but the tagged layout is better as the tag creates a niche with 254 invalid values,
114 // allowing types like `Option<Option<CanBeNicheFilledButShouldnt>>` to fit into 8 bytes.
115 pub enum CanBeNicheFilledButShouldnt {
116     A(NonZeroU8, u32),
117     B
118 }
119 pub enum AlwaysTaggedBecauseItHasNoNiche {
120     A(u8, u32),
121     B
122 }
123
124 pub enum NicheFilledMultipleFields {
125     A(bool, u8),
126     B(u8),
127     C(u8),
128     D(bool),
129     E,
130     F,
131     G,
132 }
133
134 struct BoolInTheMiddle(std::num::NonZeroU16, bool, u8);
135
136 enum NicheWithData {
137     A,
138     B([u16; 5]),
139     Largest { a1: u32, a2: BoolInTheMiddle, a3: u32 },
140     C,
141     D(u32, u32),
142 }
143
144 // A type with almost 2^16 invalid values.
145 #[repr(u16)]
146 pub enum NicheU16 {
147     _0,
148 }
149
150 pub enum EnumManyVariant<X> {
151     Dataful(u8, X),
152
153     // 0x100 niche variants.
154     _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, _0A, _0B, _0C, _0D, _0E, _0F,
155     _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _1A, _1B, _1C, _1D, _1E, _1F,
156     _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _2A, _2B, _2C, _2D, _2E, _2F,
157     _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _3A, _3B, _3C, _3D, _3E, _3F,
158     _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _4A, _4B, _4C, _4D, _4E, _4F,
159     _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _5A, _5B, _5C, _5D, _5E, _5F,
160     _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _6A, _6B, _6C, _6D, _6E, _6F,
161     _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _7A, _7B, _7C, _7D, _7E, _7F,
162     _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _8A, _8B, _8C, _8D, _8E, _8F,
163     _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9A, _9B, _9C, _9D, _9E, _9F,
164     _A0, _A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8, _A9, _AA, _AB, _AC, _AD, _AE, _AF,
165     _B0, _B1, _B2, _B3, _B4, _B5, _B6, _B7, _B8, _B9, _BA, _BB, _BC, _BD, _BE, _BF,
166     _C0, _C1, _C2, _C3, _C4, _C5, _C6, _C7, _C8, _C9, _CA, _CB, _CC, _CD, _CE, _CF,
167     _D0, _D1, _D2, _D3, _D4, _D5, _D6, _D7, _D8, _D9, _DA, _DB, _DC, _DD, _DE, _DF,
168     _E0, _E1, _E2, _E3, _E4, _E5, _E6, _E7, _E8, _E9, _EA, _EB, _EC, _ED, _EE, _EF,
169     _F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _FA, _FB, _FC, _FD, _FE, _FF,
170 }
171
172 struct Reorder4 {
173     a: u32,
174     b: u8,
175     ary: [u8; 4],
176 }
177
178 struct Reorder2 {
179     a: u16,
180     b: u8,
181     ary: [u8; 6],
182 }
183
184 pub fn main() {
185     assert_eq!(size_of::<u8>(), 1 as usize);
186     assert_eq!(size_of::<u32>(), 4 as usize);
187     assert_eq!(size_of::<char>(), 4 as usize);
188     assert_eq!(size_of::<i8>(), 1 as usize);
189     assert_eq!(size_of::<i32>(), 4 as usize);
190     assert_eq!(size_of::<t>(), 2 as usize);
191     assert_eq!(size_of::<u>(), 3 as usize);
192     // Alignment causes padding before the char and the u32.
193
194     assert_eq!(size_of::<v>(),
195                 16 as usize);
196     assert_eq!(size_of::<isize>(), size_of::<usize>());
197     assert_eq!(size_of::<w>(), size_of::<isize>());
198     assert_eq!(size_of::<x>(), size_of::<isize>());
199     assert_eq!(size_of::<isize>(), size_of::<y>());
200
201     // Make sure enum types are the appropriate size, mostly
202     // around ensuring alignment is handled properly
203
204     assert_eq!(size_of::<e1>(), 8 as usize);
205     assert_eq!(size_of::<e2>(), 8 as usize);
206     assert_eq!(size_of::<e3>(), 4 as usize);
207     assert_eq!(size_of::<ReorderedStruct>(), 4);
208     assert_eq!(size_of::<ReorderedEnum>(), 6);
209     assert_eq!(size_of::<ReorderedEnum2>(), 8);
210
211
212     assert_eq!(size_of::<EnumEmpty>(), 0);
213     assert_eq!(size_of::<EnumSingle1>(), 0);
214     assert_eq!(size_of::<EnumSingle2>(), 0);
215     assert_eq!(size_of::<EnumSingle3>(), 0);
216     assert_eq!(size_of::<EnumSingle4>(), 1);
217     assert_eq!(size_of::<EnumSingle5>(), 1);
218
219     assert_eq!(size_of::<EnumWithMaybeUninhabitedVariant<!>>(),
220                size_of::<EnumWithMaybeUninhabitedVariant<()>>());
221     assert_eq!(size_of::<NicheFilledEnumWithAbsentVariant>(), size_of::<&'static ()>());
222
223     assert_eq!(size_of::<Option<Option<(bool, &())>>>(), size_of::<(bool, &())>());
224     assert_eq!(size_of::<Option<Option<(&(), bool)>>>(), size_of::<(bool, &())>());
225     assert_eq!(size_of::<Option<Option2<bool, &()>>>(), size_of::<(bool, &())>());
226     assert_eq!(size_of::<Option<Option2<&(), bool>>>(), size_of::<(bool, &())>());
227
228     assert_eq!(size_of::<CanBeNicheFilledButShouldnt>(), 8);
229     assert_eq!(size_of::<Option<CanBeNicheFilledButShouldnt>>(), 8);
230     assert_eq!(size_of::<Option<Option<CanBeNicheFilledButShouldnt>>>(), 8);
231     assert_eq!(size_of::<AlwaysTaggedBecauseItHasNoNiche>(), 8);
232     assert_eq!(size_of::<Option<AlwaysTaggedBecauseItHasNoNiche>>(), 8);
233     assert_eq!(size_of::<Option<Option<AlwaysTaggedBecauseItHasNoNiche>>>(), 8);
234
235     assert_eq!(size_of::<NicheFilledMultipleFields>(), 2);
236     assert_eq!(size_of::<Option<NicheFilledMultipleFields>>(), 2);
237     assert_eq!(size_of::<Option<Option<NicheFilledMultipleFields>>>(), 2);
238
239     struct S1{ a: u16, b: std::num::NonZeroU16, c: u16, d: u8, e: u32, f: u64, g:[u8;2] }
240     assert_eq!(size_of::<S1>(), 24);
241     assert_eq!(size_of::<Option<S1>>(), 24);
242
243     assert_eq!(size_of::<NicheWithData>(), 12);
244     assert_eq!(size_of::<Option<NicheWithData>>(), 12);
245     assert_eq!(size_of::<Option<Option<NicheWithData>>>(), 12);
246     assert_eq!(
247         size_of::<Option<Option2<&(), Option<NicheWithData>>>>(),
248         size_of::<(&(), NicheWithData)>()
249     );
250
251     pub enum FillPadding { A(std::num::NonZeroU8, u32), B }
252     assert_eq!(size_of::<FillPadding>(), 8);
253     assert_eq!(size_of::<Option<FillPadding>>(), 8);
254     assert_eq!(size_of::<Option<Option<FillPadding>>>(), 8);
255
256     assert_eq!(size_of::<Result<(std::num::NonZeroU8, u8, u8), u16>>(), 4);
257     assert_eq!(size_of::<Option<Result<(std::num::NonZeroU8, u8, u8), u16>>>(), 4);
258     assert_eq!(size_of::<Result<(std::num::NonZeroU8, u8, u8, u8), u16>>(), 4);
259
260     assert_eq!(size_of::<EnumManyVariant<u16>>(), 6);
261     assert_eq!(size_of::<EnumManyVariant<NicheU16>>(), 4);
262     assert_eq!(size_of::<EnumManyVariant<Option<NicheU16>>>(), 4);
263     assert_eq!(size_of::<EnumManyVariant<Option2<NicheU16,u8>>>(), 6);
264     assert_eq!(size_of::<EnumManyVariant<Option<(NicheU16,u8)>>>(), 6);
265
266
267     let v = Reorder4 {a: 0, b: 0, ary: [0; 4]};
268     assert_eq!(size_of::<Reorder4>(), 12);
269     assert!((&v.ary).as_ptr().is_aligned_to(4), "[u8; 4] should group with align-4 fields");
270     let v = Reorder2 {a: 0, b: 0, ary: [0; 6]};
271     assert_eq!(size_of::<Reorder2>(), 10);
272     assert!((&v.ary).as_ptr().is_aligned_to(2), "[u8; 6] should group with align-2 fields");
273 }