Skip to content

Commit

Permalink
Fix for #62691: use the largest niche across all fields
Browse files Browse the repository at this point in the history
fixes #62691
  • Loading branch information
ogoffart committed Mar 25, 2020
1 parent 02046a5 commit 4d77d01
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 14 deletions.
25 changes: 11 additions & 14 deletions src/librustc/ty/layout.rs
Expand Up @@ -282,8 +282,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {

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

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

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

let mut sized = true;
let mut offsets = vec![Size::ZERO; fields.len()];
let mut offset = Size::ZERO;
let mut largest_niche = None;
let mut largest_niche_available = 0;
Expand Down Expand Up @@ -907,18 +907,15 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
let count = (niche_variants.end().as_u32()
- niche_variants.start().as_u32()
+ 1) as u128;
// FIXME(#62691) use the largest niche across all fields,
// not just the first one.
for (field_index, &field) in variants[i].iter().enumerate() {
let niche = match &field.largest_niche {
Some(niche) => niche,
_ => continue,
};
let (niche_start, niche_scalar) = match niche.reserve(self, count) {
Some(pair) => pair,
None => continue,
};

if let Some((field_index, niche, (niche_start, niche_scalar))) = variants[i]
.iter()
.enumerate()
.filter_map(|(i, &field)| {
let niche = field.largest_niche.as_ref()?;
Some((i, niche, niche.reserve(self, count)?))
})
.max_by_key(|(_, niche, _)| niche.available(dl))
{
let mut align = dl.aggregate_align;
let st = variants
.iter_enumerated()
Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/type-sizes.rs
Expand Up @@ -74,6 +74,11 @@ enum NicheFilledEnumWithAbsentVariant {
C,
}

enum Option2<A, B> {
Some(A, B),
None
}

pub fn main() {
assert_eq!(size_of::<u8>(), 1 as usize);
assert_eq!(size_of::<u32>(), 4 as usize);
Expand Down Expand Up @@ -113,4 +118,6 @@ pub fn main() {

assert_eq!(size_of::<Option<Option<(bool, &())>>>(), size_of::<(bool, &())>());
assert_eq!(size_of::<Option<Option<(&(), bool)>>>(), size_of::<(bool, &())>());
assert_eq!(size_of::<Option<Option2<bool, &()>>>(), size_of::<(bool, &())>());
assert_eq!(size_of::<Option<Option2<&(), bool>>>(), size_of::<(bool, &())>());
}

0 comments on commit 4d77d01

Please sign in to comment.