Skip to content

Commit acc0cc7

Browse files
committed
Add more enum layout tests
1 parent 82d30ee commit acc0cc7

File tree

2 files changed

+320
-1
lines changed

2 files changed

+320
-1
lines changed

tests/ui/layout/enum.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,96 @@ enum ScalarPairDifferingSign { //~ERROR: abi: ScalarPair
2222
A(u8),
2323
B(i8),
2424
}
25+
26+
// Enums with only a single inhabited variant can be laid out as just that variant,
27+
// if the uninhabited variants are all "absent" (only have 1-ZST fields)
28+
#[rustc_layout(size, abi)]
29+
enum AbsentVariantUntagged { //~ERROR: size: Size(4 bytes)
30+
//~^ ERROR: abi: Scalar(Initialized
31+
A(i32),
32+
B((), !),
33+
}
34+
35+
// Even if uninhabited variants are not absent, the enum can still be laid out without
36+
// a tag.
37+
#[rustc_layout(size, abi)]
38+
enum UninhabitedVariantUntagged { //~ERROR: size: Size(4 bytes)
39+
//~^ ERROR: abi: Scalar(Initialized
40+
A(i32),
41+
B(i32, !),
42+
}
43+
44+
// A single-inhabited-variant enum may still be laid out with a tag,
45+
// if that leads to a better niche for the same size layout.
46+
// This enum uses the tagged representation, since the untagged representation would be
47+
// the same size, but without a niche.
48+
#[rustc_layout(size, abi)]
49+
enum UninhabitedVariantUntaggedBigger { //~ERROR: size: Size(8 bytes)
50+
//~^ ERROR: abi: ScalarPair
51+
A(i32),
52+
B([u8; 5], !),
53+
}
54+
55+
#[rustc_layout(size, abi)]
56+
enum UninhabitedVariantWithNiche { //~ERROR: size: Size(2 bytes)
57+
//~^ERROR: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=1 }, Initialized { value: Int(I8, true), valid_range: 0..=255 })
58+
A(i8, bool),
59+
B(u8, u8, !),
60+
}
61+
62+
#[rustc_layout(debug)]
63+
enum UninhabitedVariantLargeWithNiche {
64+
//~^ ERROR: layout_of
65+
//~| ERROR: size: Size(3 bytes)
66+
//~| ERROR: backend_repr: Memory
67+
//~| ERROR: valid_range: 0..=0
68+
// Should use the tagged representation, since that gives a 255-slot niche,
69+
// instead of a 254-slot niche if it used the niche-filling representation on the `bool`
70+
A(i8, bool),
71+
B(u8, u8, u8, !),
72+
}
73+
74+
// This uses the tagged layout, but since all variants are uninhabited, none of them store the tag,
75+
// so we only need space for the fields, and the abi is Memory.
76+
#[rustc_layout(size, abi)]
77+
enum AllUninhabitedVariants { //~ERROR: size: Size(2 bytes)
78+
//~^ERROR: abi: Memory
79+
A(i8, bool, !),
80+
B(u8, u8, !),
81+
}
82+
83+
#[repr(align(2))]
84+
struct AlignedNever(!);
85+
86+
// Tagged `(i8, padding)`
87+
#[rustc_layout(size, abi)]
88+
enum AlignedI8 { //~ERROR: size: Size(2 bytes)
89+
//~^ERROR: abi: Memory
90+
A(i8),
91+
B(AlignedNever)
92+
}
93+
94+
// Tagged `(u8, i8, padding, padding)`
95+
#[rustc_layout(size, abi)]
96+
enum TaggedI8 { //~ERROR: size: Size(4 bytes)
97+
//~^ERROR: abi: Memory
98+
A(i8),
99+
B(i8, i8, i8, AlignedNever)
100+
}
101+
102+
103+
// Tagged `(u16, i16)`
104+
#[rustc_layout(size, abi)]
105+
enum TaggedI16 { //~ERROR: size: Size(4 bytes)
106+
//~^ERROR: abi: ScalarPair
107+
A(i16),
108+
B(i8, i8, i8, AlignedNever)
109+
}
110+
111+
// This must not use tagged representation, since it's zero-sized.
112+
#[rustc_layout(size, abi)]
113+
enum AllUninhabitedVariantsAlignedZst { //~ERROR: size: Size(0 bytes)
114+
//~^ERROR: abi: Memory
115+
A(AlignedNever),
116+
B(AlignedNever),
117+
}

tests/ui/layout/enum.stderr

Lines changed: 227 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,231 @@ error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=1 }
1616
LL | enum ScalarPairDifferingSign {
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

19-
error: aborting due to 3 previous errors
19+
error: size: Size(4 bytes)
20+
--> $DIR/enum.rs:29:1
21+
|
22+
LL | enum AbsentVariantUntagged {
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
25+
error: abi: Scalar(Initialized { value: Int(I32, true), valid_range: 0..=4294967295 })
26+
--> $DIR/enum.rs:29:1
27+
|
28+
LL | enum AbsentVariantUntagged {
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
30+
31+
error: size: Size(4 bytes)
32+
--> $DIR/enum.rs:38:1
33+
|
34+
LL | enum UninhabitedVariantUntagged {
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
36+
37+
error: abi: Scalar(Initialized { value: Int(I32, true), valid_range: 0..=4294967295 })
38+
--> $DIR/enum.rs:38:1
39+
|
40+
LL | enum UninhabitedVariantUntagged {
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42+
43+
error: size: Size(8 bytes)
44+
--> $DIR/enum.rs:49:1
45+
|
46+
LL | enum UninhabitedVariantUntaggedBigger {
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
48+
49+
error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=0 }, Initialized { value: Int(I32, true), valid_range: 0..=4294967295 })
50+
--> $DIR/enum.rs:49:1
51+
|
52+
LL | enum UninhabitedVariantUntaggedBigger {
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
54+
55+
error: size: Size(2 bytes)
56+
--> $DIR/enum.rs:56:1
57+
|
58+
LL | enum UninhabitedVariantWithNiche {
59+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
60+
61+
error: abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=1 }, Initialized { value: Int(I8, true), valid_range: 0..=255 })
62+
--> $DIR/enum.rs:56:1
63+
|
64+
LL | enum UninhabitedVariantWithNiche {
65+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66+
67+
error: layout_of(UninhabitedVariantLargeWithNiche) = Layout {
68+
size: Size(3 bytes),
69+
align: AbiAlign {
70+
abi: Align(1 bytes),
71+
},
72+
backend_repr: Memory {
73+
sized: true,
74+
},
75+
fields: Arbitrary {
76+
offsets: [
77+
Size(0 bytes),
78+
],
79+
memory_index: [
80+
0,
81+
],
82+
},
83+
largest_niche: Some(
84+
Niche {
85+
offset: Size(0 bytes),
86+
value: Int(
87+
I8,
88+
false,
89+
),
90+
valid_range: 0..=0,
91+
},
92+
),
93+
uninhabited: false,
94+
variants: Multiple {
95+
tag: Initialized {
96+
value: Int(
97+
I8,
98+
false,
99+
),
100+
valid_range: 0..=0,
101+
},
102+
tag_encoding: Direct,
103+
tag_field: 0,
104+
variants: [
105+
Layout {
106+
size: Size(3 bytes),
107+
align: AbiAlign {
108+
abi: Align(1 bytes),
109+
},
110+
backend_repr: Memory {
111+
sized: true,
112+
},
113+
fields: Arbitrary {
114+
offsets: [
115+
Size(1 bytes),
116+
Size(2 bytes),
117+
],
118+
memory_index: [
119+
0,
120+
1,
121+
],
122+
},
123+
largest_niche: Some(
124+
Niche {
125+
offset: Size(2 bytes),
126+
value: Int(
127+
I8,
128+
false,
129+
),
130+
valid_range: 0..=1,
131+
},
132+
),
133+
uninhabited: false,
134+
variants: Single {
135+
index: 0,
136+
variants: None,
137+
},
138+
max_repr_align: None,
139+
unadjusted_abi_align: Align(1 bytes),
140+
randomization_seed: 17394913183323368564,
141+
},
142+
Layout {
143+
size: Size(3 bytes),
144+
align: AbiAlign {
145+
abi: Align(1 bytes),
146+
},
147+
backend_repr: Memory {
148+
sized: true,
149+
},
150+
fields: Arbitrary {
151+
offsets: [
152+
Size(0 bytes),
153+
Size(1 bytes),
154+
Size(2 bytes),
155+
Size(3 bytes),
156+
],
157+
memory_index: [
158+
0,
159+
1,
160+
2,
161+
3,
162+
],
163+
},
164+
largest_niche: None,
165+
uninhabited: true,
166+
variants: Single {
167+
index: 1,
168+
variants: None,
169+
},
170+
max_repr_align: None,
171+
unadjusted_abi_align: Align(1 bytes),
172+
randomization_seed: 17538183959353994357,
173+
},
174+
],
175+
},
176+
max_repr_align: None,
177+
unadjusted_abi_align: Align(1 bytes),
178+
randomization_seed: 15362464571658798427,
179+
}
180+
--> $DIR/enum.rs:63:1
181+
|
182+
LL | enum UninhabitedVariantLargeWithNiche {
183+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
184+
185+
error: size: Size(2 bytes)
186+
--> $DIR/enum.rs:77:1
187+
|
188+
LL | enum AllUninhabitedVariants {
189+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
190+
191+
error: abi: Memory { sized: true }
192+
--> $DIR/enum.rs:77:1
193+
|
194+
LL | enum AllUninhabitedVariants {
195+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
196+
197+
error: size: Size(2 bytes)
198+
--> $DIR/enum.rs:88:1
199+
|
200+
LL | enum AlignedI8 {
201+
| ^^^^^^^^^^^^^^
202+
203+
error: abi: Memory { sized: true }
204+
--> $DIR/enum.rs:88:1
205+
|
206+
LL | enum AlignedI8 {
207+
| ^^^^^^^^^^^^^^
208+
209+
error: size: Size(4 bytes)
210+
--> $DIR/enum.rs:96:1
211+
|
212+
LL | enum TaggedI8 {
213+
| ^^^^^^^^^^^^^
214+
215+
error: abi: Memory { sized: true }
216+
--> $DIR/enum.rs:96:1
217+
|
218+
LL | enum TaggedI8 {
219+
| ^^^^^^^^^^^^^
220+
221+
error: size: Size(4 bytes)
222+
--> $DIR/enum.rs:105:1
223+
|
224+
LL | enum TaggedI16 {
225+
| ^^^^^^^^^^^^^^
226+
227+
error: abi: ScalarPair(Initialized { value: Int(I16, false), valid_range: 0..=0 }, Initialized { value: Int(I16, true), valid_range: 0..=65535 })
228+
--> $DIR/enum.rs:105:1
229+
|
230+
LL | enum TaggedI16 {
231+
| ^^^^^^^^^^^^^^
232+
233+
error: size: Size(0 bytes)
234+
--> $DIR/enum.rs:113:1
235+
|
236+
LL | enum AllUninhabitedVariantsAlignedZst {
237+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
238+
239+
error: abi: Memory { sized: true }
240+
--> $DIR/enum.rs:113:1
241+
|
242+
LL | enum AllUninhabitedVariantsAlignedZst {
243+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
244+
245+
error: aborting due to 22 previous errors
20246

0 commit comments

Comments
 (0)