Skip to content

Commit f4e8f99

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

19 files changed

Lines changed: 406 additions & 576 deletions

compiler/rustc_abi/src/layout.rs

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

707707
// It'll fit, but we need to make some adjustments.
708-
match layout.fields {
709-
FieldsShape::Arbitrary { ref mut offsets, .. } => {
710-
for offset in offsets.iter_mut() {
711-
*offset += this_offset;
712-
}
713-
}
714-
FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => {
715-
panic!("Layout of fields should be Arbitrary for variants")
716-
}
708+
for offset in layout.field_offsets.iter_mut() {
709+
*offset += this_offset;
717710
}
718711

719712
// It can't be a Scalar or ScalarPair because the offset isn't 0.
@@ -953,23 +946,16 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
953946
let old_ity_size = min_ity.size();
954947
let new_ity_size = ity.size();
955948
for variant in &mut layout_variants {
956-
match variant.fields {
957-
FieldsShape::Arbitrary { ref mut offsets, .. } => {
958-
for i in offsets {
959-
if *i <= old_ity_size {
960-
assert_eq!(*i, old_ity_size);
961-
*i = new_ity_size;
962-
}
963-
}
964-
// We might be making the struct larger.
965-
if variant.size <= old_ity_size {
966-
variant.size = new_ity_size;
967-
}
968-
}
969-
FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => {
970-
panic!("encountered a non-arbitrary layout during enum layout")
949+
for i in &mut variant.field_offsets {
950+
if *i <= old_ity_size {
951+
assert_eq!(*i, old_ity_size);
952+
*i = new_ity_size;
971953
}
972954
}
955+
// We might be making the struct larger.
956+
if variant.size <= old_ity_size {
957+
variant.size = new_ity_size;
958+
}
973959
}
974960
}
975961

@@ -994,12 +980,10 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
994980
let mut common_prim = None;
995981
let mut common_prim_initialized_in_all_variants = true;
996982
for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) {
997-
let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
998-
panic!("encountered a non-arbitrary layout during enum layout");
999-
};
1000983
// We skip *all* ZST here and later check if we are good in terms of alignment.
1001984
// This lets us handle some cases involving aligned ZST.
1002-
let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst());
985+
let mut fields = iter::zip(field_layouts, &layout_variant.field_offsets)
986+
.filter(|p| !p.0.is_zst());
1003987
let (field, offset) = match (fields.next(), fields.next()) {
1004988
(None, None) => {
1005989
common_prim_initialized_in_all_variants = false;
@@ -1094,8 +1078,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10941078
for variant in &mut layout_variants {
10951079
// We only do this for variants with fields; the others are not accessed anyway.
10961080
// Also do not overwrite any already existing "clever" ABIs.
1097-
if variant.fields.count() > 0
1098-
&& matches!(variant.backend_repr, BackendRepr::Memory { .. })
1081+
if matches!(variant.backend_repr, BackendRepr::Memory { .. } if variant.has_fields())
10991082
{
11001083
variant.backend_repr = abi;
11011084
// 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
@@ -2347,7 +2347,8 @@ pub struct VariantLayout<FieldIdx: Idx> {
23472347
pub size: Size,
23482348
pub align: AbiAlign,
23492349
pub backend_repr: BackendRepr,
2350-
pub fields: FieldsShape<FieldIdx>,
2350+
pub field_offsets: IndexVec<FieldIdx, Size>,
2351+
fields_in_memory_order: IndexVec<u32, FieldIdx>,
23512352
largest_niche: Option<Niche>,
23522353
uninhabited: bool,
23532354
max_repr_align: Option<Align>,
@@ -2357,11 +2358,16 @@ pub struct VariantLayout<FieldIdx: Idx> {
23572358

23582359
impl<FieldIdx: Idx> VariantLayout<FieldIdx> {
23592360
pub fn from_layout(layout: LayoutData<FieldIdx, impl Idx>) -> Self {
2361+
let FieldsShape::Arbitrary { offsets, in_memory_order } = layout.fields else {
2362+
panic!("Layout of fields should be Arbitrary for variants");
2363+
};
2364+
23602365
Self {
23612366
size: layout.size,
23622367
align: layout.align,
23632368
backend_repr: layout.backend_repr,
2364-
fields: layout.fields,
2369+
field_offsets: offsets,
2370+
fields_in_memory_order: in_memory_order,
23652371
largest_niche: layout.largest_niche,
23662372
uninhabited: layout.uninhabited,
23672373
max_repr_align: layout.max_repr_align,
@@ -2373,4 +2379,8 @@ impl<FieldIdx: Idx> VariantLayout<FieldIdx> {
23732379
pub fn is_uninhabited(&self) -> bool {
23742380
self.uninhabited
23752381
}
2382+
2383+
pub fn has_fields(&self) -> bool {
2384+
self.field_offsets.len() > 0
2385+
}
23762386
}

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

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

compiler/rustc_ty_utils/src/layout/invariant.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
319319
)
320320
}
321321
// Skip empty variants.
322-
if variant.size == Size::ZERO
323-
|| variant.fields.count() == 0
324-
|| variant.is_uninhabited()
325-
{
322+
if variant.size == Size::ZERO || !variant.has_fields() || variant.is_uninhabited() {
326323
// These are never actually accessed anyway, so we can skip the coherence check
327324
// for them. They also fail that check, since they may have
328325
// 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: 40 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,8 @@ error: layout_of(E) = Layout {
6666
backend_repr: Memory {
6767
sized: true,
6868
},
69-
fields: Arbitrary {
70-
offsets: [],
71-
in_memory_order: [],
72-
},
69+
field_offsets: [],
70+
fields_in_memory_order: [],
7371
largest_niche: None,
7472
uninhabited: false,
7573
max_repr_align: None,
@@ -84,18 +82,16 @@ error: layout_of(E) = Layout {
8482
backend_repr: Memory {
8583
sized: true,
8684
},
87-
fields: Arbitrary {
88-
offsets: [
89-
Size(4 bytes),
90-
Size(4 bytes),
91-
Size(8 bytes),
92-
],
93-
in_memory_order: [
94-
0,
95-
1,
96-
2,
97-
],
98-
},
85+
field_offsets: [
86+
Size(4 bytes),
87+
Size(4 bytes),
88+
Size(8 bytes),
89+
],
90+
fields_in_memory_order: [
91+
0,
92+
1,
93+
2,
94+
],
9995
largest_niche: None,
10096
uninhabited: true,
10197
max_repr_align: None,
@@ -257,14 +253,12 @@ error: layout_of(Result<i32, i32>) = Layout {
257253
valid_range: 0..=4294967295,
258254
},
259255
),
260-
fields: Arbitrary {
261-
offsets: [
262-
Size(4 bytes),
263-
],
264-
in_memory_order: [
265-
0,
266-
],
267-
},
256+
field_offsets: [
257+
Size(4 bytes),
258+
],
259+
fields_in_memory_order: [
260+
0,
261+
],
268262
largest_niche: None,
269263
uninhabited: false,
270264
max_repr_align: None,
@@ -292,14 +286,12 @@ error: layout_of(Result<i32, i32>) = Layout {
292286
valid_range: 0..=4294967295,
293287
},
294288
),
295-
fields: Arbitrary {
296-
offsets: [
297-
Size(4 bytes),
298-
],
299-
in_memory_order: [
300-
0,
301-
],
302-
},
289+
field_offsets: [
290+
Size(4 bytes),
291+
],
292+
fields_in_memory_order: [
293+
0,
294+
],
303295
largest_niche: None,
304296
uninhabited: false,
305297
max_repr_align: None,
@@ -658,10 +650,8 @@ error: layout_of(Option<bool>) = Layout {
658650
backend_repr: Memory {
659651
sized: true,
660652
},
661-
fields: Arbitrary {
662-
offsets: [],
663-
in_memory_order: [],
664-
},
653+
field_offsets: [],
654+
fields_in_memory_order: [],
665655
largest_niche: None,
666656
uninhabited: false,
667657
max_repr_align: None,
@@ -682,14 +672,12 @@ error: layout_of(Option<bool>) = Layout {
682672
valid_range: 0..=1,
683673
},
684674
),
685-
fields: Arbitrary {
686-
offsets: [
687-
Size(0 bytes),
688-
],
689-
in_memory_order: [
690-
0,
691-
],
692-
},
675+
field_offsets: [
676+
Size(0 bytes),
677+
],
678+
fields_in_memory_order: [
679+
0,
680+
],
693681
largest_niche: Some(
694682
Niche {
695683
offset: Size(0 bytes),
@@ -772,10 +760,8 @@ error: layout_of(Option<char>) = Layout {
772760
backend_repr: Memory {
773761
sized: true,
774762
},
775-
fields: Arbitrary {
776-
offsets: [],
777-
in_memory_order: [],
778-
},
763+
field_offsets: [],
764+
fields_in_memory_order: [],
779765
largest_niche: None,
780766
uninhabited: false,
781767
max_repr_align: None,
@@ -796,14 +782,12 @@ error: layout_of(Option<char>) = Layout {
796782
valid_range: 0..=1114111,
797783
},
798784
),
799-
fields: Arbitrary {
800-
offsets: [
801-
Size(0 bytes),
802-
],
803-
in_memory_order: [
804-
0,
805-
],
806-
},
785+
field_offsets: [
786+
Size(0 bytes),
787+
],
788+
fields_in_memory_order: [
789+
0,
790+
],
807791
largest_niche: Some(
808792
Niche {
809793
offset: Size(0 bytes),

0 commit comments

Comments
 (0)