1
Fork 0

Put LayoutError behind reference to shrink result

`LayoutError` is 24 bytes, which is bigger than the `Ok` types, so let's
shrink that.
This commit is contained in:
Nilstrieb 2023-04-30 23:05:27 +02:00
parent 6162f6f123
commit 3019c1cb2a
13 changed files with 89 additions and 56 deletions

View file

@ -72,7 +72,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
} }
sym::pref_align_of => { sym::pref_align_of => {
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?; let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(*e)))?;
ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx) ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx)
} }
sym::type_id => { sym::type_id => {

View file

@ -21,7 +21,7 @@ pub fn check_validity_requirement<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
kind: ValidityRequirement, kind: ValidityRequirement,
param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
) -> Result<bool, LayoutError<'tcx>> { ) -> Result<bool, &'tcx LayoutError<'tcx>> {
let layout = tcx.layout_of(param_env_and_ty)?; let layout = tcx.layout_of(param_env_and_ty)?;
// There is nothing strict or lax about inhabitedness. // There is nothing strict or lax about inhabitedness.
@ -43,7 +43,7 @@ fn might_permit_raw_init_strict<'tcx>(
ty: TyAndLayout<'tcx>, ty: TyAndLayout<'tcx>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
kind: ValidityRequirement, kind: ValidityRequirement,
) -> Result<bool, LayoutError<'tcx>> { ) -> Result<bool, &'tcx LayoutError<'tcx>> {
let machine = CompileTimeInterpreter::new(CanAccessStatics::No, CheckAlignment::Error); let machine = CompileTimeInterpreter::new(CanAccessStatics::No, CheckAlignment::Error);
let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine); let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
@ -75,7 +75,7 @@ fn might_permit_raw_init_lax<'tcx>(
this: TyAndLayout<'tcx>, this: TyAndLayout<'tcx>,
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
init_kind: ValidityRequirement, init_kind: ValidityRequirement,
) -> Result<bool, LayoutError<'tcx>> { ) -> Result<bool, &'tcx LayoutError<'tcx>> {
let scalar_allows_raw_init = move |s: Scalar| -> bool { let scalar_allows_raw_init = move |s: Scalar| -> bool {
match init_kind { match init_kind {
ValidityRequirement::Inhabited => { ValidityRequirement::Inhabited => {

View file

@ -81,7 +81,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
// Try to display a sensible error with as much information as possible. // Try to display a sensible error with as much information as possible.
let skeleton_string = |ty: Ty<'tcx>, sk| match sk { let skeleton_string = |ty: Ty<'tcx>, sk: Result<_, &_>| match sk {
Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"), Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"),
Ok(SizeSkeleton::Known(size)) => { Ok(SizeSkeleton::Known(size)) => {
if let Some(v) = u128::from(size.bytes()).checked_mul(8) { if let Some(v) = u128::from(size.bytes()).checked_mul(8) {
@ -101,7 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
Err(LayoutError::Unknown(bad)) => { Err(LayoutError::Unknown(bad)) => {
if bad == ty { if *bad == ty {
"this type does not have a fixed size".to_owned() "this type does not have a fixed size".to_owned()
} else { } else {
format!("size can vary because of {bad}") format!("size can vary because of {bad}")

View file

@ -96,15 +96,17 @@ impl EraseType for Result<ty::GenericArg<'_>, traits::query::NoSolution> {
type Result = [u8; size_of::<Result<ty::GenericArg<'static>, traits::query::NoSolution>>()]; type Result = [u8; size_of::<Result<ty::GenericArg<'static>, traits::query::NoSolution>>()];
} }
impl EraseType for Result<bool, ty::layout::LayoutError<'_>> { impl EraseType for Result<bool, &ty::layout::LayoutError<'_>> {
type Result = [u8; size_of::<Result<bool, ty::layout::LayoutError<'static>>>()]; type Result = [u8; size_of::<Result<bool, &'static ty::layout::LayoutError<'static>>>()];
} }
impl EraseType for Result<rustc_target::abi::TyAndLayout<'_, Ty<'_>>, ty::layout::LayoutError<'_>> { impl EraseType
for Result<rustc_target::abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::LayoutError<'_>>
{
type Result = [u8; size_of::< type Result = [u8; size_of::<
Result< Result<
rustc_target::abi::TyAndLayout<'static, Ty<'static>>, rustc_target::abi::TyAndLayout<'static, Ty<'static>>,
ty::layout::LayoutError<'static>, &'static ty::layout::LayoutError<'static>,
>, >,
>()]; >()];
} }

View file

@ -1383,7 +1383,7 @@ rustc_queries! {
/// executes in "reveal all" mode, and will normalize the input type. /// executes in "reveal all" mode, and will normalize the input type.
query layout_of( query layout_of(
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>> key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
) -> Result<ty::layout::TyAndLayout<'tcx>, ty::layout::LayoutError<'tcx>> { ) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
depth_limit depth_limit
desc { "computing layout of `{}`", key.value } desc { "computing layout of `{}`", key.value }
} }
@ -2164,7 +2164,7 @@ rustc_queries! {
separate_provide_extern separate_provide_extern
} }
query check_validity_requirement(key: (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>)) -> Result<bool, ty::layout::LayoutError<'tcx>> { query check_validity_requirement(key: (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>)) -> Result<bool, &'tcx ty::layout::LayoutError<'tcx>> {
desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 } desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 }
} }

View file

@ -310,7 +310,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
ty: Ty<'tcx>, ty: Ty<'tcx>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> Result<SizeSkeleton<'tcx>, LayoutError<'tcx>> { ) -> Result<SizeSkeleton<'tcx>, &'tcx LayoutError<'tcx>> {
debug_assert!(!ty.has_non_region_infer()); debug_assert!(!ty.has_non_region_infer());
// First try computing a static layout. // First try computing a static layout.
@ -353,13 +353,13 @@ impl<'tcx> SizeSkeleton<'tcx> {
let size = s let size = s
.bytes() .bytes()
.checked_mul(c) .checked_mul(c)
.ok_or_else(|| LayoutError::SizeOverflow(ty))?; .ok_or_else(|| &*tcx.arena.alloc(LayoutError::SizeOverflow(ty)))?;
return Ok(SizeSkeleton::Known(Size::from_bytes(size))); return Ok(SizeSkeleton::Known(Size::from_bytes(size)));
} }
let len = tcx.expand_abstract_consts(len); let len = tcx.expand_abstract_consts(len);
let prev = ty::Const::from_target_usize(tcx, s.bytes()); let prev = ty::Const::from_target_usize(tcx, s.bytes());
let Some(gen_size) = mul_sorted_consts(tcx, param_env, len, prev) else { let Some(gen_size) = mul_sorted_consts(tcx, param_env, len, prev) else {
return Err(LayoutError::SizeOverflow(ty)); return Err(tcx.arena.alloc(LayoutError::SizeOverflow(ty)));
}; };
Ok(SizeSkeleton::Generic(gen_size)) Ok(SizeSkeleton::Generic(gen_size))
} }
@ -367,7 +367,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
SizeSkeleton::Generic(g) => { SizeSkeleton::Generic(g) => {
let len = tcx.expand_abstract_consts(len); let len = tcx.expand_abstract_consts(len);
let Some(gen_size) = mul_sorted_consts(tcx, param_env, len, g) else { let Some(gen_size) = mul_sorted_consts(tcx, param_env, len, g) else {
return Err(LayoutError::SizeOverflow(ty)); return Err(tcx.arena.alloc(LayoutError::SizeOverflow(ty)));
}; };
Ok(SizeSkeleton::Generic(gen_size)) Ok(SizeSkeleton::Generic(gen_size))
} }
@ -672,7 +672,7 @@ pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> {
MaybeResult::from( MaybeResult::from(
tcx.layout_of(self.param_env().and(ty)) tcx.layout_of(self.param_env().and(ty))
.map_err(|err| self.handle_layout_err(err, span, ty)), .map_err(|err| self.handle_layout_err(*err, span, ty)),
) )
} }
} }
@ -680,16 +680,21 @@ pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> {
impl<'tcx, C: LayoutOfHelpers<'tcx>> LayoutOf<'tcx> for C {} impl<'tcx, C: LayoutOfHelpers<'tcx>> LayoutOf<'tcx> for C {}
impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxt<'tcx>> { impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxt<'tcx>> {
type LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>; type LayoutOfResult = Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>>;
#[inline] #[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> LayoutError<'tcx> { fn handle_layout_err(
err &self,
err: LayoutError<'tcx>,
_: Span,
_: Ty<'tcx>,
) -> &'tcx LayoutError<'tcx> {
self.tcx.arena.alloc(err)
} }
} }
impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxtAt<'tcx>> { impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxtAt<'tcx>> {
type LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>; type LayoutOfResult = Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>>;
#[inline] #[inline]
fn layout_tcx_at_span(&self) -> Span { fn layout_tcx_at_span(&self) -> Span {
@ -697,8 +702,13 @@ impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxtAt<'tcx>> {
} }
#[inline] #[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> LayoutError<'tcx> { fn handle_layout_err(
err &self,
err: LayoutError<'tcx>,
_: Span,
_: Ty<'tcx>,
) -> &'tcx LayoutError<'tcx> {
self.tcx.arena.alloc(err)
} }
} }

View file

@ -106,9 +106,12 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::EarlyBinder<ty::Binder<'_, ty::F
} }
} }
impl<'tcx, T> Value<TyCtxt<'tcx>, DepKind> for Result<T, ty::layout::LayoutError<'_>> { impl<'tcx, T> Value<TyCtxt<'tcx>, DepKind> for Result<T, &'_ ty::layout::LayoutError<'_>> {
fn from_cycle_error(_tcx: TyCtxt<'tcx>, _cycle: &[QueryInfo<DepKind>]) -> Self { fn from_cycle_error(_tcx: TyCtxt<'tcx>, _cycle: &[QueryInfo<DepKind>]) -> Self {
Err(ty::layout::LayoutError::Cycle) // tcx.arena.alloc cannot be used because we are not allowed to use &'tcx LayoutError under
// min_specialization. Since this is an error path anyways, leaking doesn't matter (and really,
// tcx.arena.alloc is pretty much equal to leaking).
Err(Box::leak(Box::new(ty::layout::LayoutError::Cycle)))
} }
} }

View file

@ -94,6 +94,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
Err(layout_error) => { Err(layout_error) => {
tcx.sess.emit_fatal(Spanned { tcx.sess.emit_fatal(Spanned {
node: layout_error.into_diagnostic(), node: layout_error.into_diagnostic(),
span: tcx.def_span(item_def_id.to_def_id()), span: tcx.def_span(item_def_id.to_def_id()),
}); });
} }

View file

@ -192,8 +192,8 @@ pub(crate) mod rustc {
TypeError(ErrorGuaranteed), TypeError(ErrorGuaranteed),
} }
impl<'tcx> From<LayoutError<'tcx>> for Err { impl<'tcx> From<&LayoutError<'tcx>> for Err {
fn from(err: LayoutError<'tcx>) -> Self { fn from(err: &LayoutError<'tcx>) -> Self {
match err { match err {
LayoutError::Unknown(..) => Self::UnknownLayout, LayoutError::Unknown(..) => Self::UnknownLayout,
err => unimplemented!("{:?}", err), err => unimplemented!("{:?}", err),
@ -221,7 +221,7 @@ pub(crate) mod rustc {
} }
impl LayoutSummary { impl LayoutSummary {
fn from_ty<'tcx>(ty: Ty<'tcx>, ctx: TyCtxt<'tcx>) -> Result<Self, LayoutError<'tcx>> { fn from_ty<'tcx>(ty: Ty<'tcx>, ctx: TyCtxt<'tcx>) -> Result<Self, &'tcx LayoutError<'tcx>> {
use rustc_middle::ty::ParamEnvAnd; use rustc_middle::ty::ParamEnvAnd;
use rustc_target::abi::{TyAndLayout, Variants}; use rustc_target::abi::{TyAndLayout, Variants};
@ -482,7 +482,7 @@ pub(crate) mod rustc {
fn layout_of<'tcx>( fn layout_of<'tcx>(
ctx: TyCtxt<'tcx>, ctx: TyCtxt<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Result<alloc::Layout, LayoutError<'tcx>> { ) -> Result<alloc::Layout, &'tcx LayoutError<'tcx>> {
use rustc_middle::ty::ParamEnvAnd; use rustc_middle::ty::ParamEnvAnd;
use rustc_target::abi::TyAndLayout; use rustc_target::abi::TyAndLayout;

View file

@ -386,7 +386,7 @@ fn fn_abi_new_uncached<'tcx>(
_ => bug!("argument to drop_in_place is not a raw ptr: {:?}", ty), _ => bug!("argument to drop_in_place is not a raw ptr: {:?}", ty),
}); });
let layout = cx.layout_of(ty)?; let layout = cx.layout_of(ty).map_err(|err| *err)?;
let layout = if force_thin_self_ptr && arg_idx == Some(0) { let layout = if force_thin_self_ptr && arg_idx == Some(0) {
// Don't pass the vtable, it's not an argument of the virtual fn. // Don't pass the vtable, it's not an argument of the virtual fn.
// Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait` // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`

View file

@ -31,7 +31,7 @@ pub fn provide(providers: &mut Providers) {
fn layout_of<'tcx>( fn layout_of<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
) -> Result<TyAndLayout<'tcx>, LayoutError<'tcx>> { ) -> Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>> {
let (param_env, ty) = query.into_parts(); let (param_env, ty) = query.into_parts();
debug!(?ty); debug!(?ty);
@ -45,7 +45,9 @@ fn layout_of<'tcx>(
let ty = match tcx.try_normalize_erasing_regions(param_env, ty) { let ty = match tcx.try_normalize_erasing_regions(param_env, ty) {
Ok(t) => t, Ok(t) => t,
Err(normalization_error) => { Err(normalization_error) => {
return Err(LayoutError::NormalizationFailure(ty, normalization_error)); return Err(tcx
.arena
.alloc(LayoutError::NormalizationFailure(ty, normalization_error)));
} }
}; };
@ -66,27 +68,34 @@ fn layout_of<'tcx>(
Ok(layout) Ok(layout)
} }
fn error<'tcx>(
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
err: LayoutError<'tcx>,
) -> &'tcx LayoutError<'tcx> {
cx.tcx.arena.alloc(err)
}
fn univariant_uninterned<'tcx>( fn univariant_uninterned<'tcx>(
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
fields: &IndexSlice<FieldIdx, Layout<'_>>, fields: &IndexSlice<FieldIdx, Layout<'_>>,
repr: &ReprOptions, repr: &ReprOptions,
kind: StructKind, kind: StructKind,
) -> Result<LayoutS, LayoutError<'tcx>> { ) -> Result<LayoutS, &'tcx LayoutError<'tcx>> {
let dl = cx.data_layout(); let dl = cx.data_layout();
let pack = repr.pack; let pack = repr.pack;
if pack.is_some() && repr.align.is_some() { if pack.is_some() && repr.align.is_some() {
cx.tcx.sess.delay_span_bug(DUMMY_SP, "struct cannot be packed and aligned"); cx.tcx.sess.delay_span_bug(DUMMY_SP, "struct cannot be packed and aligned");
return Err(LayoutError::Unknown(ty)); return Err(cx.tcx.arena.alloc(LayoutError::Unknown(ty)));
} }
cx.univariant(dl, fields, repr, kind).ok_or(LayoutError::SizeOverflow(ty)) cx.univariant(dl, fields, repr, kind).ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))
} }
fn layout_of_uncached<'tcx>( fn layout_of_uncached<'tcx>(
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Result<Layout<'tcx>, LayoutError<'tcx>> { ) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> {
let tcx = cx.tcx; let tcx = cx.tcx;
let param_env = cx.param_env; let param_env = cx.param_env;
let dl = cx.data_layout(); let dl = cx.data_layout();
@ -170,7 +179,7 @@ fn layout_of_uncached<'tcx>(
err = better_err; err = better_err;
} }
} }
return Err(LayoutError::NormalizationFailure(pointee, err)); return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
}, },
}; };
@ -181,7 +190,7 @@ fn layout_of_uncached<'tcx>(
} }
let Abi::Scalar(metadata) = metadata_layout.abi else { let Abi::Scalar(metadata) = metadata_layout.abi else {
return Err(LayoutError::Unknown(pointee)); return Err(error(cx, LayoutError::Unknown(pointee)));
}; };
metadata metadata
@ -199,7 +208,7 @@ fn layout_of_uncached<'tcx>(
vtable vtable
} }
_ => { _ => {
return Err(LayoutError::Unknown(pointee)); return Err(error(cx, LayoutError::Unknown(pointee)));
} }
} }
}; };
@ -221,14 +230,18 @@ fn layout_of_uncached<'tcx>(
if count.has_projections() { if count.has_projections() {
count = tcx.normalize_erasing_regions(param_env, count); count = tcx.normalize_erasing_regions(param_env, count);
if count.has_projections() { if count.has_projections() {
return Err(LayoutError::Unknown(ty)); return Err(error(cx, LayoutError::Unknown(ty)));
} }
} }
let count = let count = count
count.try_eval_target_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?; .try_eval_target_usize(tcx, param_env)
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
let element = cx.layout_of(element)?; let element = cx.layout_of(element)?;
let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?; let size = element
.size
.checked_mul(count, dl)
.ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?;
let abi = if count != 0 && ty.is_privately_uninhabited(tcx, param_env) { let abi = if count != 0 && ty.is_privately_uninhabited(tcx, param_env) {
Abi::Uninhabited Abi::Uninhabited
@ -316,7 +329,7 @@ fn layout_of_uncached<'tcx>(
DUMMY_SP, DUMMY_SP,
"#[repr(simd)] was applied to an ADT that is not a struct", "#[repr(simd)] was applied to an ADT that is not a struct",
); );
return Err(LayoutError::Unknown(ty)); return Err(error(cx, LayoutError::Unknown(ty)));
} }
let fields = &def.non_enum_variant().fields; let fields = &def.non_enum_variant().fields;
@ -346,7 +359,7 @@ fn layout_of_uncached<'tcx>(
DUMMY_SP, DUMMY_SP,
"#[repr(simd)] was applied to an ADT with heterogeneous field type", "#[repr(simd)] was applied to an ADT with heterogeneous field type",
); );
return Err(LayoutError::Unknown(ty)); return Err(error(cx, LayoutError::Unknown(ty)));
} }
} }
@ -368,7 +381,7 @@ fn layout_of_uncached<'tcx>(
// Extract the number of elements from the layout of the array field: // Extract the number of elements from the layout of the array field:
let FieldsShape::Array { count, .. } = cx.layout_of(f0_ty)?.layout.fields() else { let FieldsShape::Array { count, .. } = cx.layout_of(f0_ty)?.layout.fields() else {
return Err(LayoutError::Unknown(ty)); return Err(error(cx, LayoutError::Unknown(ty)));
}; };
(*e_ty, *count, true) (*e_ty, *count, true)
@ -397,7 +410,10 @@ fn layout_of_uncached<'tcx>(
}; };
// Compute the size and alignment of the vector: // Compute the size and alignment of the vector:
let size = e_ly.size.checked_mul(e_len, dl).ok_or(LayoutError::SizeOverflow(ty))?; let size = e_ly
.size
.checked_mul(e_len, dl)
.ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?;
let align = dl.vector_align(size); let align = dl.vector_align(size);
let size = size.align_to(align.abi); let size = size.align_to(align.abi);
@ -438,11 +454,12 @@ fn layout_of_uncached<'tcx>(
tcx.def_span(def.did()), tcx.def_span(def.did()),
"union cannot be packed and aligned", "union cannot be packed and aligned",
); );
return Err(LayoutError::Unknown(ty)); return Err(error(cx, LayoutError::Unknown(ty)));
} }
return Ok(tcx.mk_layout( return Ok(tcx.mk_layout(
cx.layout_of_union(&def.repr(), &variants).ok_or(LayoutError::Unknown(ty))?, cx.layout_of_union(&def.repr(), &variants)
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?,
)); ));
} }
@ -476,7 +493,7 @@ fn layout_of_uncached<'tcx>(
} }
}, },
) )
.ok_or(LayoutError::SizeOverflow(ty))?, .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?,
) )
} }
@ -484,7 +501,7 @@ fn layout_of_uncached<'tcx>(
ty::Alias(..) => { ty::Alias(..) => {
// NOTE(eddyb) `layout_of` query should've normalized these away, // NOTE(eddyb) `layout_of` query should've normalized these away,
// if that was possible, so there's no reason to try again here. // if that was possible, so there's no reason to try again here.
return Err(LayoutError::Unknown(ty)); return Err(error(cx, LayoutError::Unknown(ty)));
} }
ty::Bound(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) | ty::Infer(_) => { ty::Bound(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) | ty::Infer(_) => {
@ -492,7 +509,7 @@ fn layout_of_uncached<'tcx>(
} }
ty::Placeholder(..) | ty::Param(_) | ty::Error(_) => { ty::Placeholder(..) | ty::Param(_) | ty::Error(_) => {
return Err(LayoutError::Unknown(ty)); return Err(error(cx, LayoutError::Unknown(ty)));
} }
}) })
} }
@ -628,13 +645,13 @@ fn generator_layout<'tcx>(
ty: Ty<'tcx>, ty: Ty<'tcx>,
def_id: hir::def_id::DefId, def_id: hir::def_id::DefId,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
) -> Result<Layout<'tcx>, LayoutError<'tcx>> { ) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> {
use SavedLocalEligibility::*; use SavedLocalEligibility::*;
let tcx = cx.tcx; 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).subst(tcx, substs);
let Some(info) = tcx.generator_layout(def_id) else { let Some(info) = tcx.generator_layout(def_id) else {
return Err(LayoutError::Unknown(ty)); return Err(error(cx, LayoutError::Unknown(ty)));
}; };
let (ineligible_locals, assignments) = generator_saved_local_eligibility(&info); let (ineligible_locals, assignments) = generator_saved_local_eligibility(&info);

View file

@ -17,7 +17,7 @@ use crate::html::render::Context;
#[template(path = "type_layout.html")] #[template(path = "type_layout.html")]
struct TypeLayout<'cx> { struct TypeLayout<'cx> {
variants: Vec<(Symbol, TypeLayoutSize)>, variants: Vec<(Symbol, TypeLayoutSize)>,
type_layout_size: Result<TypeLayoutSize, LayoutError<'cx>>, type_layout_size: Result<TypeLayoutSize, &'cx LayoutError<'cx>>,
} }
#[derive(Template)] #[derive(Template)]

View file

@ -311,7 +311,7 @@ pub struct PrimitiveLayouts<'tcx> {
} }
impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> { impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, LayoutError<'tcx>> { fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, &'tcx LayoutError<'tcx>> {
let tcx = layout_cx.tcx; let tcx = layout_cx.tcx;
let mut_raw_ptr = tcx.mk_ptr(TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Mut }); let mut_raw_ptr = tcx.mk_ptr(TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Mut });
let const_raw_ptr = tcx.mk_ptr(TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Not }); let const_raw_ptr = tcx.mk_ptr(TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Not });