summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_ty_utils/src/layout.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
commitd1b2d29528b7794b41e66fc2136e395a02f8529b (patch)
treea4a17504b260206dec3cf55b2dca82929a348ac2 /compiler/rustc_ty_utils/src/layout.rs
parentReleasing progress-linux version 1.72.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-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.rs80
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(),