Skip to content

Commit 4d77d01

Browse files
committed
Fix for #62691: use the largest niche across all fields
fixes #62691
1 parent 02046a5 commit 4d77d01

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

Diff for: src/librustc/ty/layout.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
282282

283283
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
284284

285-
let mut sized = true;
286-
let mut offsets = vec![Size::ZERO; fields.len()];
287285
let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();
288286

289287
let mut optimize = !repr.inhibit_struct_field_reordering_opt();
@@ -320,6 +318,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
320318
// At the bottom of this function, we invert `inverse_memory_index` to
321319
// produce `memory_index` (see `invert_mapping`).
322320

321+
let mut sized = true;
322+
let mut offsets = vec![Size::ZERO; fields.len()];
323323
let mut offset = Size::ZERO;
324324
let mut largest_niche = None;
325325
let mut largest_niche_available = 0;
@@ -907,18 +907,15 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
907907
let count = (niche_variants.end().as_u32()
908908
- niche_variants.start().as_u32()
909909
+ 1) as u128;
910-
// FIXME(#62691) use the largest niche across all fields,
911-
// not just the first one.
912-
for (field_index, &field) in variants[i].iter().enumerate() {
913-
let niche = match &field.largest_niche {
914-
Some(niche) => niche,
915-
_ => continue,
916-
};
917-
let (niche_start, niche_scalar) = match niche.reserve(self, count) {
918-
Some(pair) => pair,
919-
None => continue,
920-
};
921-
910+
if let Some((field_index, niche, (niche_start, niche_scalar))) = variants[i]
911+
.iter()
912+
.enumerate()
913+
.filter_map(|(i, &field)| {
914+
let niche = field.largest_niche.as_ref()?;
915+
Some((i, niche, niche.reserve(self, count)?))
916+
})
917+
.max_by_key(|(_, niche, _)| niche.available(dl))
918+
{
922919
let mut align = dl.aggregate_align;
923920
let st = variants
924921
.iter_enumerated()

Diff for: src/test/ui/type-sizes.rs

+7
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ enum NicheFilledEnumWithAbsentVariant {
7474
C,
7575
}
7676

77+
enum Option2<A, B> {
78+
Some(A, B),
79+
None
80+
}
81+
7782
pub fn main() {
7883
assert_eq!(size_of::<u8>(), 1 as usize);
7984
assert_eq!(size_of::<u32>(), 4 as usize);
@@ -113,4 +118,6 @@ pub fn main() {
113118

114119
assert_eq!(size_of::<Option<Option<(bool, &())>>>(), size_of::<(bool, &())>());
115120
assert_eq!(size_of::<Option<Option<(&(), bool)>>>(), size_of::<(bool, &())>());
121+
assert_eq!(size_of::<Option<Option2<bool, &()>>>(), size_of::<(bool, &())>());
122+
assert_eq!(size_of::<Option<Option2<&(), bool>>>(), size_of::<(bool, &())>());
116123
}

0 commit comments

Comments
 (0)