]> git.proxmox.com Git - rustc.git/blob - src/test/ui/type-sizes.rs
New upstream version 1.51.0+dfsg1
[rustc.git] / src / test / ui / type-sizes.rs
1 // run-pass
2
3 #![allow(non_camel_case_types)]
4 #![allow(dead_code)]
5 #![feature(never_type)]
6
7 use std::mem::size_of;
8 use std::num::NonZeroU8;
9
10 struct t {a: u8, b: i8}
11 struct u {a: u8, b: i8, c: u8}
12 struct v {a: u8, b: i8, c: v2, d: u32}
13 struct v2 {u: char, v: u8}
14 struct w {a: isize, b: ()}
15 struct x {a: isize, b: (), c: ()}
16 struct y {x: isize}
17
18 enum e1 {
19 a(u8, u32), b(u32), c
20 }
21 enum e2 {
22 a(u32), b
23 }
24
25 #[repr(C, u8)]
26 enum e3 {
27 a([u16; 0], u8), b
28 }
29
30 struct ReorderedStruct {
31 a: u8,
32 b: u16,
33 c: u8
34 }
35
36 enum ReorderedEnum {
37 A(u8, u16, u8),
38 B(u8, u16, u8),
39 }
40
41 enum ReorderedEnum2 {
42 A(u8, u32, u8),
43 B(u16, u8, u16, u8),
44
45 // 0x100 niche variants.
46 _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, _0A, _0B, _0C, _0D, _0E, _0F,
47 _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _1A, _1B, _1C, _1D, _1E, _1F,
48 _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _2A, _2B, _2C, _2D, _2E, _2F,
49 _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _3A, _3B, _3C, _3D, _3E, _3F,
50 _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _4A, _4B, _4C, _4D, _4E, _4F,
51 _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _5A, _5B, _5C, _5D, _5E, _5F,
52 _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _6A, _6B, _6C, _6D, _6E, _6F,
53 _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _7A, _7B, _7C, _7D, _7E, _7F,
54 _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _8A, _8B, _8C, _8D, _8E, _8F,
55 _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9A, _9B, _9C, _9D, _9E, _9F,
56 _A0, _A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8, _A9, _AA, _AB, _AC, _AD, _AE, _AF,
57 _B0, _B1, _B2, _B3, _B4, _B5, _B6, _B7, _B8, _B9, _BA, _BB, _BC, _BD, _BE, _BF,
58 _C0, _C1, _C2, _C3, _C4, _C5, _C6, _C7, _C8, _C9, _CA, _CB, _CC, _CD, _CE, _CF,
59 _D0, _D1, _D2, _D3, _D4, _D5, _D6, _D7, _D8, _D9, _DA, _DB, _DC, _DD, _DE, _DF,
60 _E0, _E1, _E2, _E3, _E4, _E5, _E6, _E7, _E8, _E9, _EA, _EB, _EC, _ED, _EE, _EF,
61 _F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _FA, _FB, _FC, _FD, _FE, _FF,
62 }
63
64 enum EnumEmpty {}
65
66 enum EnumSingle1 {
67 A,
68 }
69
70 enum EnumSingle2 {
71 A = 42 as isize,
72 }
73
74 enum EnumSingle3 {
75 A,
76 B(!),
77 }
78
79 #[repr(u8)]
80 enum EnumSingle4 {
81 A,
82 }
83
84 #[repr(u8)]
85 enum EnumSingle5 {
86 A = 42 as u8,
87 }
88
89 enum EnumWithMaybeUninhabitedVariant<T> {
90 A(&'static ()),
91 B(&'static (), T),
92 C,
93 }
94
95 enum NicheFilledEnumWithAbsentVariant {
96 A(&'static ()),
97 B((), !),
98 C,
99 }
100
101 enum Option2<A, B> {
102 Some(A, B),
103 None
104 }
105
106 // Two layouts are considered for `CanBeNicheFilledButShouldnt`:
107 // Niche-filling:
108 // { u32 (4 bytes), NonZeroU8 + tag in niche (1 byte), padding (3 bytes) }
109 // Tagged:
110 // { tag (1 byte), NonZeroU8 (1 byte), padding (2 bytes), u32 (4 bytes) }
111 // Both are the same size (due to padding),
112 // but the tagged layout is better as the tag creates a niche with 254 invalid values,
113 // allowing types like `Option<Option<CanBeNicheFilledButShouldnt>>` to fit into 8 bytes.
114 pub enum CanBeNicheFilledButShouldnt {
115 A(NonZeroU8, u32),
116 B
117 }
118 pub enum AlwaysTaggedBecauseItHasNoNiche {
119 A(u8, u32),
120 B
121 }
122
123 pub fn main() {
124 assert_eq!(size_of::<u8>(), 1 as usize);
125 assert_eq!(size_of::<u32>(), 4 as usize);
126 assert_eq!(size_of::<char>(), 4 as usize);
127 assert_eq!(size_of::<i8>(), 1 as usize);
128 assert_eq!(size_of::<i32>(), 4 as usize);
129 assert_eq!(size_of::<t>(), 2 as usize);
130 assert_eq!(size_of::<u>(), 3 as usize);
131 // Alignment causes padding before the char and the u32.
132
133 assert_eq!(size_of::<v>(),
134 16 as usize);
135 assert_eq!(size_of::<isize>(), size_of::<usize>());
136 assert_eq!(size_of::<w>(), size_of::<isize>());
137 assert_eq!(size_of::<x>(), size_of::<isize>());
138 assert_eq!(size_of::<isize>(), size_of::<y>());
139
140 // Make sure enum types are the appropriate size, mostly
141 // around ensuring alignment is handled properly
142
143 assert_eq!(size_of::<e1>(), 8 as usize);
144 assert_eq!(size_of::<e2>(), 8 as usize);
145 assert_eq!(size_of::<e3>(), 4 as usize);
146 assert_eq!(size_of::<ReorderedStruct>(), 4);
147 assert_eq!(size_of::<ReorderedEnum>(), 6);
148 assert_eq!(size_of::<ReorderedEnum2>(), 8);
149
150
151 assert_eq!(size_of::<EnumEmpty>(), 0);
152 assert_eq!(size_of::<EnumSingle1>(), 0);
153 assert_eq!(size_of::<EnumSingle2>(), 0);
154 assert_eq!(size_of::<EnumSingle3>(), 0);
155 assert_eq!(size_of::<EnumSingle4>(), 1);
156 assert_eq!(size_of::<EnumSingle5>(), 1);
157
158 assert_eq!(size_of::<EnumWithMaybeUninhabitedVariant<!>>(),
159 size_of::<EnumWithMaybeUninhabitedVariant<()>>());
160 assert_eq!(size_of::<NicheFilledEnumWithAbsentVariant>(), size_of::<&'static ()>());
161
162 assert_eq!(size_of::<Option<Option<(bool, &())>>>(), size_of::<(bool, &())>());
163 assert_eq!(size_of::<Option<Option<(&(), bool)>>>(), size_of::<(bool, &())>());
164 assert_eq!(size_of::<Option<Option2<bool, &()>>>(), size_of::<(bool, &())>());
165 assert_eq!(size_of::<Option<Option2<&(), bool>>>(), size_of::<(bool, &())>());
166
167 assert_eq!(size_of::<CanBeNicheFilledButShouldnt>(), 8);
168 assert_eq!(size_of::<Option<CanBeNicheFilledButShouldnt>>(), 8);
169 assert_eq!(size_of::<Option<Option<CanBeNicheFilledButShouldnt>>>(), 8);
170 assert_eq!(size_of::<AlwaysTaggedBecauseItHasNoNiche>(), 8);
171 assert_eq!(size_of::<Option<AlwaysTaggedBecauseItHasNoNiche>>(), 8);
172 assert_eq!(size_of::<Option<Option<AlwaysTaggedBecauseItHasNoNiche>>>(), 8);
173 }