diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:59:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:59:35 +0000 |
commit | d1b2d29528b7794b41e66fc2136e395a02f8529b (patch) | |
tree | a4a17504b260206dec3cf55b2dca82929a348ac2 /compiler/rustc_ty_utils/src/layout.rs | |
parent | Releasing progress-linux version 1.72.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.tar.xz rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.zip |
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_ty_utils/src/layout.rs')
-rw-r--r-- | compiler/rustc_ty_utils/src/layout.rs | 80 |
1 files changed, 55 insertions, 25 deletions
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index b67cd96a7..6b4273c03 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::layout::{ IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, }; use rustc_middle::ty::{ - self, subst::SubstsRef, AdtDef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitableExt, + self, AdtDef, EarlyBinder, GenericArgsRef, ReprOptions, Ty, TyCtxt, TypeVisitableExt, }; use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use rustc_span::symbol::Symbol; @@ -96,6 +96,13 @@ fn layout_of_uncached<'tcx>( cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, ty: Ty<'tcx>, ) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> { + // Types that reference `ty::Error` pessimistically don't have a meaningful layout. + // The only side-effect of this is possibly worse diagnostics in case the layout + // was actually computable (like if the `ty::Error` showed up only in a `PhantomData`). + if let Err(guar) = ty.error_reported() { + return Err(error(cx, LayoutError::ReferencesError(guar))); + } + let tcx = cx.tcx; let param_env = cx.param_env; let dl = cx.data_layout(); @@ -258,6 +265,8 @@ fn layout_of_uncached<'tcx>( largest_niche, align: element.align, size, + max_repr_align: None, + unadjusted_abi_align: element.align.abi, }) } ty::Slice(element) => { @@ -269,6 +278,8 @@ fn layout_of_uncached<'tcx>( largest_niche: None, align: element.align, size: Size::ZERO, + max_repr_align: None, + unadjusted_abi_align: element.align.abi, }) } ty::Str => tcx.mk_layout(LayoutS { @@ -278,6 +289,8 @@ fn layout_of_uncached<'tcx>( largest_niche: None, align: dl.i8_align, size: Size::ZERO, + max_repr_align: None, + unadjusted_abi_align: dl.i8_align.abi, }), // Odd unit types. @@ -299,12 +312,14 @@ fn layout_of_uncached<'tcx>( tcx.mk_layout(unit) } - ty::Generator(def_id, substs, _) => generator_layout(cx, ty, def_id, substs)?, + ty::Generator(def_id, args, _) => generator_layout(cx, ty, def_id, args)?, - ty::Closure(_, ref substs) => { - let tys = substs.as_closure().upvar_tys(); + ty::Closure(_, ref args) => { + let tys = args.as_closure().upvar_tys(); univariant( - &tys.map(|ty| Ok(cx.layout_of(ty)?.layout)).try_collect::<IndexVec<_, _>>()?, + &tys.iter() + .map(|ty| Ok(cx.layout_of(ty)?.layout)) + .try_collect::<IndexVec<_, _>>()?, &ReprOptions::default(), StructKind::AlwaysSized, )? @@ -322,7 +337,7 @@ fn layout_of_uncached<'tcx>( } // SIMD vector types. - ty::Adt(def, substs) if def.repr().simd() => { + ty::Adt(def, args) if def.repr().simd() => { if !def.is_struct() { // Should have yielded E0517 by now. tcx.sess.delay_span_bug( @@ -349,12 +364,12 @@ fn layout_of_uncached<'tcx>( } // Type of the first ADT field: - let f0_ty = fields[FieldIdx::from_u32(0)].ty(tcx, substs); + let f0_ty = fields[FieldIdx::from_u32(0)].ty(tcx, args); // Heterogeneous SIMD vectors are not supported: // (should be caught by typeck) for fi in fields { - if fi.ty(tcx, substs) != f0_ty { + if fi.ty(tcx, args) != f0_ty { tcx.sess.delay_span_bug( DUMMY_SP, "#[repr(simd)] was applied to an ADT with heterogeneous field type", @@ -431,11 +446,13 @@ fn layout_of_uncached<'tcx>( largest_niche: e_ly.largest_niche, size, align, + max_repr_align: None, + unadjusted_abi_align: align.abi, }) } // ADTs. - ty::Adt(def, substs) => { + ty::Adt(def, args) => { // Cache the field layouts. let variants = def .variants() @@ -443,7 +460,7 @@ fn layout_of_uncached<'tcx>( .map(|v| { v.fields .iter() - .map(|field| Ok(cx.layout_of(field.ty(tcx, substs))?.layout)) + .map(|field| Ok(cx.layout_of(field.ty(tcx, args))?.layout)) .try_collect::<IndexVec<_, _>>() }) .try_collect::<IndexVec<VariantIdx, _>>()?; @@ -482,7 +499,7 @@ fn layout_of_uncached<'tcx>( let maybe_unsized = def.is_struct() && def.non_enum_variant().tail_opt().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) + !tcx.type_of(last_field.did).instantiate_identity().is_sized(tcx, param_env) }); let Some(layout) = cx.layout_of_struct_or_enum( @@ -502,7 +519,7 @@ fn layout_of_uncached<'tcx>( // If the struct tail is sized and can be unsized, check that unsizing doesn't move the fields around. if cfg!(debug_assertions) && maybe_unsized - && def.non_enum_variant().tail().ty(tcx, substs).is_sized(tcx, cx.param_env) + && def.non_enum_variant().tail().ty(tcx, args).is_sized(tcx, cx.param_env) { let mut variants = variants; let tail_replacement = cx.layout_of(Ty::new_slice(tcx, tcx.types.u8)).unwrap(); @@ -525,8 +542,13 @@ fn layout_of_uncached<'tcx>( let FieldsShape::Arbitrary { offsets: sized_offsets, .. } = &layout.fields else { bug!("unexpected FieldsShape for sized layout of {ty:?}: {:?}", layout.fields); }; - let FieldsShape::Arbitrary { offsets: unsized_offsets, .. } = &unsized_layout.fields else { - bug!("unexpected FieldsShape for unsized layout of {ty:?}: {:?}", unsized_layout.fields); + let FieldsShape::Arbitrary { offsets: unsized_offsets, .. } = + &unsized_layout.fields + else { + bug!( + "unexpected FieldsShape for unsized layout of {ty:?}: {:?}", + unsized_layout.fields + ); }; let (sized_tail, sized_fields) = sized_offsets.raw.split_last().unwrap(); @@ -551,11 +573,15 @@ fn layout_of_uncached<'tcx>( return Err(error(cx, LayoutError::Unknown(ty))); } - ty::Bound(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) | ty::Infer(_) => { + ty::Bound(..) + | ty::GeneratorWitness(..) + | ty::GeneratorWitnessMIR(..) + | ty::Infer(_) + | ty::Error(_) => { bug!("Layout::compute: unexpected type `{}`", ty) } - ty::Placeholder(..) | ty::Param(_) | ty::Error(_) => { + ty::Placeholder(..) | ty::Param(_) => { return Err(error(cx, LayoutError::Unknown(ty))); } }) @@ -691,11 +717,11 @@ fn generator_layout<'tcx>( cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, ty: Ty<'tcx>, def_id: hir::def_id::DefId, - substs: SubstsRef<'tcx>, + args: GenericArgsRef<'tcx>, ) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> { use SavedLocalEligibility::*; let tcx = cx.tcx; - let subst_field = |ty: Ty<'tcx>| EarlyBinder::bind(ty).subst(tcx, substs); + let subst_field = |ty: Ty<'tcx>| EarlyBinder::bind(ty).instantiate(tcx, args); let Some(info) = tcx.generator_layout(def_id) else { return Err(error(cx, LayoutError::Unknown(ty))); @@ -705,7 +731,7 @@ fn generator_layout<'tcx>( // Build a prefix layout, including "promoting" all ineligible // locals as part of the prefix. We compute the layout of all of // these fields at once to get optimal packing. - let tag_index = substs.as_generator().prefix_tys().count(); + let tag_index = args.as_generator().prefix_tys().len(); // `info.variant_fields` already accounts for the reserved variants, so no need to add them. let max_discr = (info.variant_fields.len() - 1) as u128; @@ -721,9 +747,10 @@ fn generator_layout<'tcx>( .map(|local| subst_field(info.field_tys[local].ty)) .map(|ty| Ty::new_maybe_uninit(tcx, ty)) .map(|ty| Ok(cx.layout_of(ty)?.layout)); - let prefix_layouts = substs + let prefix_layouts = args .as_generator() .prefix_tys() + .iter() .map(|ty| Ok(cx.layout_of(ty)?.layout)) .chain(iter::once(Ok(tag_layout))) .chain(promoted_layouts) @@ -879,6 +906,8 @@ fn generator_layout<'tcx>( largest_niche: prefix.largest_niche, size, align, + max_repr_align: None, + unadjusted_abi_align: align.abi, }); debug!("generator layout ({:?}): {:#?}", ty, layout); Ok(layout) @@ -929,11 +958,11 @@ fn record_layout_for_printing_outlined<'tcx>( record(adt_kind.into(), adt_packed, opt_discr_size, variant_infos); } - ty::Generator(def_id, substs, _) => { + ty::Generator(def_id, args, _) => { debug!("print-type-size t: `{:?}` record generator", layout.ty); // Generators always have a begin/poisoned/end state with additional suspend points let (variant_infos, opt_discr_size) = - variant_info_for_generator(cx, layout, def_id, substs); + variant_info_for_generator(cx, layout, def_id, args); record(DataTypeKind::Generator, false, opt_discr_size, variant_infos); } @@ -1023,7 +1052,7 @@ fn variant_info_for_generator<'tcx>( cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: TyAndLayout<'tcx>, def_id: DefId, - substs: ty::SubstsRef<'tcx>, + args: ty::GenericArgsRef<'tcx>, ) -> (Vec<VariantInfo>, Option<Size>) { let Variants::Multiple { tag, ref tag_encoding, tag_field, .. } = layout.variants else { return (vec![], None); @@ -1033,9 +1062,10 @@ fn variant_info_for_generator<'tcx>( let upvar_names = cx.tcx.closure_saved_names_of_captured_variables(def_id); let mut upvars_size = Size::ZERO; - let upvar_fields: Vec<_> = substs + let upvar_fields: Vec<_> = args .as_generator() .upvar_tys() + .iter() .zip(upvar_names) .enumerate() .map(|(field_idx, (_, name))| { @@ -1108,7 +1138,7 @@ fn variant_info_for_generator<'tcx>( } VariantInfo { - name: Some(Symbol::intern(&ty::GeneratorSubsts::variant_name(variant_idx))), + name: Some(Symbol::intern(&ty::GeneratorArgs::variant_name(variant_idx))), kind: SizeKind::Exact, size: variant_size.bytes(), align: variant_layout.align.abi.bytes(), |