diff options
| author | Lukas Markeffsky <@> | 2023-07-02 14:06:56 +0200 |
|---|---|---|
| committer | Lukas Markeffsky <@> | 2023-07-06 13:04:13 +0000 |
| commit | 478071ba9daabcdbc880db5638989dc16545537c (patch) | |
| tree | e48e202d7b7f58b86f189bfc515216f6be8e6173 /compiler/rustc_ty_utils/src | |
| parent | 4b6749b21e680a6280cf05ace533ae20c93d9bff (diff) | |
| download | rust-478071ba9daabcdbc880db5638989dc16545537c.tar.gz rust-478071ba9daabcdbc880db5638989dc16545537c.zip | |
clean up struct layout code
Diffstat (limited to 'compiler/rustc_ty_utils/src')
| -rw-r--r-- | compiler/rustc_ty_utils/src/layout.rs | 69 |
1 files changed, 37 insertions, 32 deletions
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 9ef9120e294..f6bc0dc330d 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -463,38 +463,43 @@ fn layout_of_uncached<'tcx>( )); } - tcx.mk_layout( - cx.layout_of_struct_or_enum( - &def.repr(), - &variants, - def.is_enum(), - def.is_unsafe_cell(), - tcx.layout_scalar_valid_range(def.did()), - |min, max| Integer::repr_discr(tcx, ty, &def.repr(), min, max), - def.is_enum() - .then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128))) - .into_iter() - .flatten(), - def.repr().inhibit_enum_layout_opt() - || def - .variants() - .iter_enumerated() - .any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32())), - { - let param_env = tcx.param_env(def.did()); - def.is_struct() - && match def.variants().iter().next().and_then(|x| x.fields.raw.last()) - { - Some(last_field) => tcx - .type_of(last_field.did) - .subst_identity() - .is_sized(tcx, param_env), - None => false, - } - }, - ) - .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?, - ) + let get_discriminant_type = + |min, max| Integer::repr_discr(tcx, ty, &def.repr(), min, max); + + let discriminants_iter = || { + def.is_enum() + .then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128))) + .into_iter() + .flatten() + }; + + let dont_niche_optimize_enum = def.repr().inhibit_enum_layout_opt() + || def + .variants() + .iter_enumerated() + .any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32())); + + let maybe_unsized = def.is_struct() + && def.non_enum_variant().fields.raw.last().is_some_and(|last_field| { + let param_env = tcx.param_env(def.did()); + !tcx.type_of(last_field.did).subst_identity().is_sized(tcx, param_env) + }); + + let Some(layout) = cx.layout_of_struct_or_enum( + &def.repr(), + &variants, + def.is_enum(), + def.is_unsafe_cell(), + tcx.layout_scalar_valid_range(def.did()), + get_discriminant_type, + discriminants_iter(), + dont_niche_optimize_enum, + !maybe_unsized, + ) else { + return Err(error(cx, LayoutError::SizeOverflow(ty))); + }; + + tcx.mk_layout(layout) } // Types with no meaningful known layout. |
