Skip to content

Commit 9ac23dd

Browse files
committed
Get rid of niche selection's dependence on fields's order
1 parent f6bcd09 commit 9ac23dd

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

compiler/rustc_abi/src/layout.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -527,15 +527,10 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
527527
let count =
528528
(niche_variants.end().index() as u128 - niche_variants.start().index() as u128) + 1;
529529

530-
// Find the field with the largest niche
531-
let (field_index, niche, (niche_start, niche_scalar)) = variants[largest_variant_index]
532-
.iter()
533-
.enumerate()
534-
.filter_map(|(j, field)| Some((j, field.largest_niche?)))
535-
.max_by_key(|(_, niche)| niche.available(dl))
536-
.and_then(|(j, niche)| Some((j, niche, niche.reserve(dl, count)?)))?;
537-
let niche_offset =
538-
niche.offset + variant_layouts[largest_variant_index].fields.offset(field_index);
530+
// Use the largest niche in the largest variant.
531+
let niche = variant_layouts[largest_variant_index].largest_niche?;
532+
let (niche_start, niche_scalar) = niche.reserve(dl, count)?;
533+
let niche_offset = niche.offset;
539534
let niche_size = niche.value.size(dl);
540535
let size = variant_layouts[largest_variant_index].size.align_to(align.abi);
541536

tests/ui/structs-enums/type-sizes.rs

+20
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,23 @@ struct ReorderEndNiche {
209209
b: MiddleNiche4,
210210
}
211211

212+
// We want that the niche selection doesn't depend on order of the fields. See issue #125630.
213+
pub enum NicheFieldOrder1 {
214+
A {
215+
x: NonZero<u64>,
216+
y: [NonZero<u64>; 2],
217+
},
218+
B([u64; 2]),
219+
}
220+
221+
pub enum NicheFieldOrder2 {
222+
A {
223+
y: [NonZero<u64>; 2],
224+
x: NonZero<u64>,
225+
},
226+
B([u64; 2]),
227+
}
228+
212229

213230
// standins for std types which we want to be laid out in a reasonable way
214231
struct RawVecDummy {
@@ -260,6 +277,9 @@ pub fn main() {
260277
size_of::<EnumWithMaybeUninhabitedVariant<()>>());
261278
assert_eq!(size_of::<NicheFilledEnumWithAbsentVariant>(), size_of::<&'static ()>());
262279

280+
assert_eq!(size_of::<NicheFieldOrder1>(), 24);
281+
assert_eq!(size_of::<NicheFieldOrder2>(), 24);
282+
263283
assert_eq!(size_of::<Option<Option<(bool, &())>>>(), size_of::<(bool, &())>());
264284
assert_eq!(size_of::<Option<Option<(&(), bool)>>>(), size_of::<(bool, &())>());
265285
assert_eq!(size_of::<Option<Option2<bool, &()>>>(), size_of::<(bool, &())>());

0 commit comments

Comments
 (0)