Skip to content

Commit f9225ae

Browse files
committed
Store FieldsShape::Arbitrary fields directly in VariantLayout
Enum variants always have `Arbitrary` layout, so the enum isn't needed.
1 parent c7a66c4 commit f9225ae

19 files changed

Lines changed: 390 additions & 552 deletions

compiler/rustc_abi/src/layout.rs

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -642,15 +642,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
642642
}
643643

644644
// It'll fit, but we need to make some adjustments.
645-
match layout.fields {
646-
FieldsShape::Arbitrary { ref mut offsets, .. } => {
647-
for offset in offsets.iter_mut() {
648-
*offset += this_offset;
649-
}
650-
}
651-
FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => {
652-
panic!("Layout of fields should be Arbitrary for variants")
653-
}
645+
for offset in layout.field_offsets.iter_mut() {
646+
*offset += this_offset;
654647
}
655648

656649
// It can't be a Scalar or ScalarPair because the offset isn't 0.
@@ -890,23 +883,16 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
890883
let old_ity_size = min_ity.size();
891884
let new_ity_size = ity.size();
892885
for variant in &mut layout_variants {
893-
match variant.fields {
894-
FieldsShape::Arbitrary { ref mut offsets, .. } => {
895-
for i in offsets {
896-
if *i <= old_ity_size {
897-
assert_eq!(*i, old_ity_size);
898-
*i = new_ity_size;
899-
}
900-
}
901-
// We might be making the struct larger.
902-
if variant.size <= old_ity_size {
903-
variant.size = new_ity_size;
904-
}
905-
}
906-
FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => {
907-
panic!("encountered a non-arbitrary layout during enum layout")
886+
for i in &mut variant.field_offsets {
887+
if *i <= old_ity_size {
888+
assert_eq!(*i, old_ity_size);
889+
*i = new_ity_size;
908890
}
909891
}
892+
// We might be making the struct larger.
893+
if variant.size <= old_ity_size {
894+
variant.size = new_ity_size;
895+
}
910896
}
911897
}
912898

@@ -931,12 +917,10 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
931917
let mut common_prim = None;
932918
let mut common_prim_initialized_in_all_variants = true;
933919
for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) {
934-
let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
935-
panic!("encountered a non-arbitrary layout during enum layout");
936-
};
937920
// We skip *all* ZST here and later check if we are good in terms of alignment.
938921
// This lets us handle some cases involving aligned ZST.
939-
let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst());
922+
let mut fields = iter::zip(field_layouts, &layout_variant.field_offsets)
923+
.filter(|p| !p.0.is_zst());
940924
let (field, offset) = match (fields.next(), fields.next()) {
941925
(None, None) => {
942926
common_prim_initialized_in_all_variants = false;
@@ -1031,8 +1015,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10311015
for variant in &mut layout_variants {
10321016
// We only do this for variants with fields; the others are not accessed anyway.
10331017
// Also do not overwrite any already existing "clever" ABIs.
1034-
if variant.fields.count() > 0
1035-
&& matches!(variant.backend_repr, BackendRepr::Memory { .. })
1018+
if matches!(variant.backend_repr, BackendRepr::Memory { .. } if variant.has_fields())
10361019
{
10371020
variant.backend_repr = abi;
10381021
// Also need to bump up the size and alignment, so that the entire value fits

compiler/rustc_abi/src/layout/simple.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,10 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
155155
};
156156

157157
Self {
158-
fields: layout.fields.clone(),
158+
fields: FieldsShape::Arbitrary {
159+
offsets: layout.field_offsets.clone(),
160+
in_memory_order: layout.fields_in_memory_order.clone(),
161+
},
159162
variants: Variants::Single { index },
160163
backend_repr: layout.backend_repr,
161164
largest_niche: layout.largest_niche,

compiler/rustc_abi/src/lib.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,7 +2238,8 @@ pub struct VariantLayout<FieldIdx: Idx> {
22382238
pub size: Size,
22392239
pub align: AbiAlign,
22402240
pub backend_repr: BackendRepr,
2241-
pub fields: FieldsShape<FieldIdx>,
2241+
pub field_offsets: IndexVec<FieldIdx, Size>,
2242+
fields_in_memory_order: IndexVec<u32, FieldIdx>,
22422243
largest_niche: Option<Niche>,
22432244
uninhabited: bool,
22442245
max_repr_align: Option<Align>,
@@ -2248,11 +2249,16 @@ pub struct VariantLayout<FieldIdx: Idx> {
22482249

22492250
impl<FieldIdx: Idx> VariantLayout<FieldIdx> {
22502251
pub fn from_layout(layout: LayoutData<FieldIdx, impl Idx>) -> Self {
2252+
let FieldsShape::Arbitrary { offsets, in_memory_order } = layout.fields else {
2253+
panic!("Layout of fields should be Arbitrary for variants");
2254+
};
2255+
22512256
Self {
22522257
size: layout.size,
22532258
align: layout.align,
22542259
backend_repr: layout.backend_repr,
2255-
fields: layout.fields,
2260+
field_offsets: offsets,
2261+
fields_in_memory_order: in_memory_order,
22562262
largest_niche: layout.largest_niche,
22572263
uninhabited: layout.uninhabited,
22582264
max_repr_align: layout.max_repr_align,
@@ -2264,4 +2270,8 @@ impl<FieldIdx: Idx> VariantLayout<FieldIdx> {
22642270
pub fn is_uninhabited(&self) -> bool {
22652271
self.uninhabited
22662272
}
2273+
2274+
pub fn has_fields(&self) -> bool {
2275+
self.field_offsets.len() > 0
2276+
}
22672277
}

compiler/rustc_public/src/unstable/convert/stable/abi.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,8 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::
215215
tag_field: tag_field.stable(tables, cx),
216216
variants: variants
217217
.iter()
218-
.map(|v| match &v.fields {
219-
rustc_abi::FieldsShape::Arbitrary { offsets, .. } => VariantFields {
220-
offsets: offsets.iter().as_slice().stable(tables, cx),
221-
},
222-
_ => panic!("variant layout should be Arbitrary"),
218+
.map(|v| VariantFields {
219+
offsets: v.field_offsets.iter().as_slice().stable(tables, cx),
223220
})
224221
.collect(),
225222
}

compiler/rustc_ty_utils/src/layout/invariant.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
310310
)
311311
}
312312
// Skip empty variants.
313-
if variant.size == Size::ZERO
314-
|| variant.fields.count() == 0
315-
|| variant.is_uninhabited()
316-
{
313+
if variant.size == Size::ZERO || !variant.has_fields() || variant.is_uninhabited() {
317314
// These are never actually accessed anyway, so we can skip the coherence check
318315
// for them. They also fail that check, since they may have
319316
// a different ABI even when the main type is

tests/ui/enum-discriminant/wrapping_niche.stderr

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,8 @@ error: layout_of(UnsignedAroundZero) = Layout {
5050
backend_repr: Memory {
5151
sized: true,
5252
},
53-
fields: Arbitrary {
54-
offsets: [],
55-
in_memory_order: [],
56-
},
53+
field_offsets: [],
54+
fields_in_memory_order: [],
5755
largest_niche: None,
5856
uninhabited: false,
5957
max_repr_align: None,
@@ -68,10 +66,8 @@ error: layout_of(UnsignedAroundZero) = Layout {
6866
backend_repr: Memory {
6967
sized: true,
7068
},
71-
fields: Arbitrary {
72-
offsets: [],
73-
in_memory_order: [],
74-
},
69+
field_offsets: [],
70+
fields_in_memory_order: [],
7571
largest_niche: None,
7672
uninhabited: false,
7773
max_repr_align: None,
@@ -86,10 +82,8 @@ error: layout_of(UnsignedAroundZero) = Layout {
8682
backend_repr: Memory {
8783
sized: true,
8884
},
89-
fields: Arbitrary {
90-
offsets: [],
91-
in_memory_order: [],
92-
},
85+
field_offsets: [],
86+
fields_in_memory_order: [],
9387
largest_niche: None,
9488
uninhabited: false,
9589
max_repr_align: None,
@@ -159,10 +153,8 @@ error: layout_of(SignedAroundZero) = Layout {
159153
backend_repr: Memory {
160154
sized: true,
161155
},
162-
fields: Arbitrary {
163-
offsets: [],
164-
in_memory_order: [],
165-
},
156+
field_offsets: [],
157+
fields_in_memory_order: [],
166158
largest_niche: None,
167159
uninhabited: false,
168160
max_repr_align: None,
@@ -177,10 +169,8 @@ error: layout_of(SignedAroundZero) = Layout {
177169
backend_repr: Memory {
178170
sized: true,
179171
},
180-
fields: Arbitrary {
181-
offsets: [],
182-
in_memory_order: [],
183-
},
172+
field_offsets: [],
173+
fields_in_memory_order: [],
184174
largest_niche: None,
185175
uninhabited: false,
186176
max_repr_align: None,
@@ -195,10 +185,8 @@ error: layout_of(SignedAroundZero) = Layout {
195185
backend_repr: Memory {
196186
sized: true,
197187
},
198-
fields: Arbitrary {
199-
offsets: [],
200-
in_memory_order: [],
201-
},
188+
field_offsets: [],
189+
fields_in_memory_order: [],
202190
largest_niche: None,
203191
uninhabited: false,
204192
max_repr_align: None,

tests/ui/layout/debug.stderr

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,8 @@ error: layout_of(E) = Layout {
5050
backend_repr: Memory {
5151
sized: true,
5252
},
53-
fields: Arbitrary {
54-
offsets: [],
55-
in_memory_order: [],
56-
},
53+
field_offsets: [],
54+
fields_in_memory_order: [],
5755
largest_niche: None,
5856
uninhabited: false,
5957
max_repr_align: None,
@@ -68,18 +66,16 @@ error: layout_of(E) = Layout {
6866
backend_repr: Memory {
6967
sized: true,
7068
},
71-
fields: Arbitrary {
72-
offsets: [
73-
Size(4 bytes),
74-
Size(4 bytes),
75-
Size(8 bytes),
76-
],
77-
in_memory_order: [
78-
0,
79-
1,
80-
2,
81-
],
82-
},
69+
field_offsets: [
70+
Size(4 bytes),
71+
Size(4 bytes),
72+
Size(8 bytes),
73+
],
74+
fields_in_memory_order: [
75+
0,
76+
1,
77+
2,
78+
],
8379
largest_niche: None,
8480
uninhabited: true,
8581
max_repr_align: None,
@@ -241,14 +237,12 @@ error: layout_of(Result<i32, i32>) = Layout {
241237
valid_range: 0..=4294967295,
242238
},
243239
),
244-
fields: Arbitrary {
245-
offsets: [
246-
Size(4 bytes),
247-
],
248-
in_memory_order: [
249-
0,
250-
],
251-
},
240+
field_offsets: [
241+
Size(4 bytes),
242+
],
243+
fields_in_memory_order: [
244+
0,
245+
],
252246
largest_niche: None,
253247
uninhabited: false,
254248
max_repr_align: None,
@@ -276,14 +270,12 @@ error: layout_of(Result<i32, i32>) = Layout {
276270
valid_range: 0..=4294967295,
277271
},
278272
),
279-
fields: Arbitrary {
280-
offsets: [
281-
Size(4 bytes),
282-
],
283-
in_memory_order: [
284-
0,
285-
],
286-
},
273+
field_offsets: [
274+
Size(4 bytes),
275+
],
276+
fields_in_memory_order: [
277+
0,
278+
],
287279
largest_niche: None,
288280
uninhabited: false,
289281
max_repr_align: None,

tests/ui/layout/hexagon-enum.stderr

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,8 @@ error: layout_of(A) = Layout {
5050
backend_repr: Memory {
5151
sized: true,
5252
},
53-
fields: Arbitrary {
54-
offsets: [],
55-
in_memory_order: [],
56-
},
53+
field_offsets: [],
54+
fields_in_memory_order: [],
5755
largest_niche: None,
5856
uninhabited: false,
5957
max_repr_align: None,
@@ -123,10 +121,8 @@ error: layout_of(B) = Layout {
123121
backend_repr: Memory {
124122
sized: true,
125123
},
126-
fields: Arbitrary {
127-
offsets: [],
128-
in_memory_order: [],
129-
},
124+
field_offsets: [],
125+
fields_in_memory_order: [],
130126
largest_niche: None,
131127
uninhabited: false,
132128
max_repr_align: None,
@@ -196,10 +192,8 @@ error: layout_of(C) = Layout {
196192
backend_repr: Memory {
197193
sized: true,
198194
},
199-
fields: Arbitrary {
200-
offsets: [],
201-
in_memory_order: [],
202-
},
195+
field_offsets: [],
196+
fields_in_memory_order: [],
203197
largest_niche: None,
204198
uninhabited: false,
205199
max_repr_align: None,
@@ -269,10 +263,8 @@ error: layout_of(P) = Layout {
269263
backend_repr: Memory {
270264
sized: true,
271265
},
272-
fields: Arbitrary {
273-
offsets: [],
274-
in_memory_order: [],
275-
},
266+
field_offsets: [],
267+
fields_in_memory_order: [],
276268
largest_niche: None,
277269
uninhabited: false,
278270
max_repr_align: None,
@@ -342,10 +334,8 @@ error: layout_of(T) = Layout {
342334
backend_repr: Memory {
343335
sized: true,
344336
},
345-
fields: Arbitrary {
346-
offsets: [],
347-
in_memory_order: [],
348-
},
337+
field_offsets: [],
338+
fields_in_memory_order: [],
349339
largest_niche: None,
350340
uninhabited: false,
351341
max_repr_align: None,

0 commit comments

Comments
 (0)