mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #111035 - Nilstrieb:layout-err, r=wesleywiser
Shrink error variants for layout and fn_abi The errors are bigger than the result, so let's put them behind a reference. Since query results have to be `Copy`, we use a reference into the arena instead of a `Box<T>`.
This commit is contained in:
commit
ba76096bf1
@ -72,7 +72,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
|
||||
}
|
||||
sym::pref_align_of => {
|
||||
// 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)
|
||||
}
|
||||
sym::type_id => {
|
||||
|
@ -21,7 +21,7 @@ pub fn check_validity_requirement<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
kind: ValidityRequirement,
|
||||
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)?;
|
||||
|
||||
// There is nothing strict or lax about inhabitedness.
|
||||
@ -43,7 +43,7 @@ fn might_permit_raw_init_strict<'tcx>(
|
||||
ty: TyAndLayout<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
kind: ValidityRequirement,
|
||||
) -> Result<bool, LayoutError<'tcx>> {
|
||||
) -> Result<bool, &'tcx LayoutError<'tcx>> {
|
||||
let machine = CompileTimeInterpreter::new(CanAccessStatics::No, CheckAlignment::Error);
|
||||
|
||||
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>,
|
||||
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
|
||||
init_kind: ValidityRequirement,
|
||||
) -> Result<bool, LayoutError<'tcx>> {
|
||||
) -> Result<bool, &'tcx LayoutError<'tcx>> {
|
||||
let scalar_allows_raw_init = move |s: Scalar| -> bool {
|
||||
match init_kind {
|
||||
ValidityRequirement::Inhabited => {
|
||||
|
@ -81,7 +81,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// 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::Known(size)) => {
|
||||
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)) => {
|
||||
if bad == ty {
|
||||
if *bad == ty {
|
||||
"this type does not have a fixed size".to_owned()
|
||||
} else {
|
||||
format!("size can vary because of {bad}")
|
||||
|
@ -71,8 +71,8 @@ impl<T> EraseType for Result<&'_ T, traits::CodegenObligationError> {
|
||||
type Result = [u8; size_of::<Result<&'static (), traits::CodegenObligationError>>()];
|
||||
}
|
||||
|
||||
impl<T> EraseType for Result<&'_ T, ty::layout::FnAbiError<'_>> {
|
||||
type Result = [u8; size_of::<Result<&'static (), ty::layout::FnAbiError<'static>>>()];
|
||||
impl<T> EraseType for Result<&'_ T, &'_ ty::layout::FnAbiError<'_>> {
|
||||
type Result = [u8; size_of::<Result<&'static (), &'static ty::layout::FnAbiError<'static>>>()];
|
||||
}
|
||||
|
||||
impl<T> EraseType for Result<(&'_ T, rustc_middle::thir::ExprId), rustc_errors::ErrorGuaranteed> {
|
||||
@ -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>>()];
|
||||
}
|
||||
|
||||
impl EraseType for Result<bool, ty::layout::LayoutError<'_>> {
|
||||
type Result = [u8; size_of::<Result<bool, ty::layout::LayoutError<'static>>>()];
|
||||
impl EraseType for Result<bool, &ty::layout::LayoutError<'_>> {
|
||||
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::<
|
||||
Result<
|
||||
rustc_target::abi::TyAndLayout<'static, Ty<'static>>,
|
||||
ty::layout::LayoutError<'static>,
|
||||
&'static ty::layout::LayoutError<'static>,
|
||||
>,
|
||||
>()];
|
||||
}
|
||||
|
@ -1383,7 +1383,7 @@ rustc_queries! {
|
||||
/// executes in "reveal all" mode, and will normalize the input type.
|
||||
query layout_of(
|
||||
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
|
||||
desc { "computing layout of `{}`", key.value }
|
||||
}
|
||||
@ -1394,7 +1394,7 @@ rustc_queries! {
|
||||
/// instead, where the instance is an `InstanceDef::Virtual`.
|
||||
query fn_abi_of_fn_ptr(
|
||||
key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
|
||||
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
|
||||
desc { "computing call ABI of `{}` function pointers", key.value.0 }
|
||||
}
|
||||
|
||||
@ -1405,7 +1405,7 @@ rustc_queries! {
|
||||
/// to an `InstanceDef::Virtual` instance (of `<dyn Trait as Trait>::fn`).
|
||||
query fn_abi_of_instance(
|
||||
key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
|
||||
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
|
||||
desc { "computing call ABI of `{}`", key.value.0 }
|
||||
}
|
||||
|
||||
@ -2164,7 +2164,7 @@ rustc_queries! {
|
||||
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 }
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
|
||||
ty: Ty<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Result<SizeSkeleton<'tcx>, LayoutError<'tcx>> {
|
||||
) -> Result<SizeSkeleton<'tcx>, &'tcx LayoutError<'tcx>> {
|
||||
debug_assert!(!ty.has_non_region_infer());
|
||||
|
||||
// First try computing a static layout.
|
||||
@ -353,13 +353,13 @@ impl<'tcx> SizeSkeleton<'tcx> {
|
||||
let size = s
|
||||
.bytes()
|
||||
.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)));
|
||||
}
|
||||
let len = tcx.expand_abstract_consts(len);
|
||||
let prev = ty::Const::from_target_usize(tcx, s.bytes());
|
||||
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))
|
||||
}
|
||||
@ -367,7 +367,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
|
||||
SizeSkeleton::Generic(g) => {
|
||||
let len = tcx.expand_abstract_consts(len);
|
||||
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))
|
||||
}
|
||||
@ -672,7 +672,7 @@ pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> {
|
||||
|
||||
MaybeResult::from(
|
||||
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> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
type LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;
|
||||
type LayoutOfResult = Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>>;
|
||||
|
||||
#[inline]
|
||||
fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> LayoutError<'tcx> {
|
||||
err
|
||||
fn handle_layout_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>> {
|
||||
type LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;
|
||||
type LayoutOfResult = Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>>;
|
||||
|
||||
#[inline]
|
||||
fn layout_tcx_at_span(&self) -> Span {
|
||||
@ -697,8 +702,13 @@ impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxtAt<'tcx>> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> LayoutError<'tcx> {
|
||||
err
|
||||
fn handle_layout_err(
|
||||
&self,
|
||||
err: LayoutError<'tcx>,
|
||||
_: Span,
|
||||
_: Ty<'tcx>,
|
||||
) -> &'tcx LayoutError<'tcx> {
|
||||
self.tcx.arena.alloc(err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1250,18 +1260,6 @@ pub enum FnAbiError<'tcx> {
|
||||
AdjustForForeignAbi(call::AdjustForForeignAbiError),
|
||||
}
|
||||
|
||||
impl<'tcx> From<LayoutError<'tcx>> for FnAbiError<'tcx> {
|
||||
fn from(err: LayoutError<'tcx>) -> Self {
|
||||
Self::Layout(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<call::AdjustForForeignAbiError> for FnAbiError<'_> {
|
||||
fn from(err: call::AdjustForForeignAbiError) -> Self {
|
||||
Self::AdjustForForeignAbi(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> IntoDiagnostic<'a, !> for FnAbiError<'b> {
|
||||
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, !> {
|
||||
match self {
|
||||
@ -1321,7 +1319,7 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
|
||||
let tcx = self.tcx().at(span);
|
||||
|
||||
MaybeResult::from(tcx.fn_abi_of_fn_ptr(self.param_env().and((sig, extra_args))).map_err(
|
||||
|err| self.handle_fn_abi_err(err, span, FnAbiRequest::OfFnPtr { sig, extra_args }),
|
||||
|err| self.handle_fn_abi_err(*err, span, FnAbiRequest::OfFnPtr { sig, extra_args }),
|
||||
))
|
||||
}
|
||||
|
||||
@ -1348,7 +1346,11 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
|
||||
// However, we don't do this early in order to avoid calling
|
||||
// `def_span` unconditionally (which may have a perf penalty).
|
||||
let span = if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) };
|
||||
self.handle_fn_abi_err(err, span, FnAbiRequest::OfInstance { instance, extra_args })
|
||||
self.handle_fn_abi_err(
|
||||
*err,
|
||||
span,
|
||||
FnAbiRequest::OfInstance { instance, extra_args },
|
||||
)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
@ -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 {
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
|
||||
Err(layout_error) => {
|
||||
tcx.sess.emit_fatal(Spanned {
|
||||
node: layout_error.into_diagnostic(),
|
||||
|
||||
span: tcx.def_span(item_def_id.to_def_id()),
|
||||
});
|
||||
}
|
||||
|
@ -192,8 +192,8 @@ pub(crate) mod rustc {
|
||||
TypeError(ErrorGuaranteed),
|
||||
}
|
||||
|
||||
impl<'tcx> From<LayoutError<'tcx>> for Err {
|
||||
fn from(err: LayoutError<'tcx>) -> Self {
|
||||
impl<'tcx> From<&LayoutError<'tcx>> for Err {
|
||||
fn from(err: &LayoutError<'tcx>) -> Self {
|
||||
match err {
|
||||
LayoutError::Unknown(..) => Self::UnknownLayout,
|
||||
err => unimplemented!("{:?}", err),
|
||||
@ -221,7 +221,7 @@ pub(crate) mod rustc {
|
||||
}
|
||||
|
||||
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_target::abi::{TyAndLayout, Variants};
|
||||
|
||||
@ -482,7 +482,7 @@ pub(crate) mod rustc {
|
||||
fn layout_of<'tcx>(
|
||||
ctx: TyCtxt<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Result<alloc::Layout, LayoutError<'tcx>> {
|
||||
) -> Result<alloc::Layout, &'tcx LayoutError<'tcx>> {
|
||||
use rustc_middle::ty::ParamEnvAnd;
|
||||
use rustc_target::abi::TyAndLayout;
|
||||
|
||||
|
@ -202,7 +202,7 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
|
||||
fn fn_abi_of_fn_ptr<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
query: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
|
||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
|
||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
|
||||
let (param_env, (sig, extra_args)) = query.into_parts();
|
||||
|
||||
let cx = LayoutCx { tcx, param_env };
|
||||
@ -212,7 +212,7 @@ fn fn_abi_of_fn_ptr<'tcx>(
|
||||
fn fn_abi_of_instance<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
query: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
|
||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
|
||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
|
||||
let (param_env, (instance, extra_args)) = query.into_parts();
|
||||
|
||||
let sig = fn_sig_for_fn_abi(tcx, instance, param_env);
|
||||
@ -331,7 +331,7 @@ fn fn_abi_new_uncached<'tcx>(
|
||||
fn_def_id: Option<DefId>,
|
||||
// FIXME(eddyb) replace this with something typed, like an `enum`.
|
||||
force_thin_self_ptr: bool,
|
||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
|
||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
|
||||
let sig = cx.tcx.normalize_erasing_late_bound_regions(cx.param_env, sig);
|
||||
|
||||
let conv = conv_from_spec_abi(cx.tcx(), sig.abi);
|
||||
@ -376,7 +376,7 @@ fn fn_abi_new_uncached<'tcx>(
|
||||
let is_drop_in_place =
|
||||
fn_def_id.is_some() && fn_def_id == cx.tcx.lang_items().drop_in_place_fn();
|
||||
|
||||
let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, FnAbiError<'tcx>> {
|
||||
let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, &'tcx FnAbiError<'tcx>> {
|
||||
let span = tracing::debug_span!("arg_of");
|
||||
let _entered = span.enter();
|
||||
let is_return = arg_idx.is_none();
|
||||
@ -386,7 +386,8 @@ fn fn_abi_new_uncached<'tcx>(
|
||||
_ => 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| &*cx.tcx.arena.alloc(FnAbiError::Layout(*err)))?;
|
||||
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.
|
||||
// Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
|
||||
@ -454,7 +455,7 @@ fn fn_abi_adjust_for_abi<'tcx>(
|
||||
fn_abi: &mut FnAbi<'tcx, Ty<'tcx>>,
|
||||
abi: SpecAbi,
|
||||
fn_def_id: Option<DefId>,
|
||||
) -> Result<(), FnAbiError<'tcx>> {
|
||||
) -> Result<(), &'tcx FnAbiError<'tcx>> {
|
||||
if abi == SpecAbi::Unadjusted {
|
||||
return Ok(());
|
||||
}
|
||||
@ -548,7 +549,9 @@ fn fn_abi_adjust_for_abi<'tcx>(
|
||||
fixup(arg, Some(arg_idx));
|
||||
}
|
||||
} else {
|
||||
fn_abi.adjust_for_foreign_abi(cx, abi)?;
|
||||
fn_abi
|
||||
.adjust_for_foreign_abi(cx, abi)
|
||||
.map_err(|err| &*cx.tcx.arena.alloc(FnAbiError::AdjustForForeignAbi(err)))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -31,7 +31,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
fn layout_of<'tcx>(
|
||||
tcx: TyCtxt<'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();
|
||||
debug!(?ty);
|
||||
|
||||
@ -45,7 +45,9 @@ fn layout_of<'tcx>(
|
||||
let ty = match tcx.try_normalize_erasing_regions(param_env, ty) {
|
||||
Ok(t) => t,
|
||||
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)
|
||||
}
|
||||
|
||||
fn error<'tcx>(
|
||||
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
|
||||
err: LayoutError<'tcx>,
|
||||
) -> &'tcx LayoutError<'tcx> {
|
||||
cx.tcx.arena.alloc(err)
|
||||
}
|
||||
|
||||
fn univariant_uninterned<'tcx>(
|
||||
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
|
||||
ty: Ty<'tcx>,
|
||||
fields: &IndexSlice<FieldIdx, Layout<'_>>,
|
||||
repr: &ReprOptions,
|
||||
kind: StructKind,
|
||||
) -> Result<LayoutS, LayoutError<'tcx>> {
|
||||
) -> Result<LayoutS, &'tcx LayoutError<'tcx>> {
|
||||
let dl = cx.data_layout();
|
||||
let pack = repr.pack;
|
||||
if pack.is_some() && repr.align.is_some() {
|
||||
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>(
|
||||
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Result<Layout<'tcx>, LayoutError<'tcx>> {
|
||||
) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> {
|
||||
let tcx = cx.tcx;
|
||||
let param_env = cx.param_env;
|
||||
let dl = cx.data_layout();
|
||||
@ -170,7 +179,7 @@ fn layout_of_uncached<'tcx>(
|
||||
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 {
|
||||
return Err(LayoutError::Unknown(pointee));
|
||||
return Err(error(cx, LayoutError::Unknown(pointee)));
|
||||
};
|
||||
|
||||
metadata
|
||||
@ -199,7 +208,7 @@ fn layout_of_uncached<'tcx>(
|
||||
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() {
|
||||
count = tcx.normalize_erasing_regions(param_env, count);
|
||||
if count.has_projections() {
|
||||
return Err(LayoutError::Unknown(ty));
|
||||
return Err(error(cx, LayoutError::Unknown(ty)));
|
||||
}
|
||||
}
|
||||
|
||||
let count =
|
||||
count.try_eval_target_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?;
|
||||
let count = count
|
||||
.try_eval_target_usize(tcx, param_env)
|
||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
||||
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) {
|
||||
Abi::Uninhabited
|
||||
@ -316,7 +329,7 @@ fn layout_of_uncached<'tcx>(
|
||||
DUMMY_SP,
|
||||
"#[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;
|
||||
@ -346,7 +359,7 @@ fn layout_of_uncached<'tcx>(
|
||||
DUMMY_SP,
|
||||
"#[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:
|
||||
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)
|
||||
@ -397,7 +410,10 @@ fn layout_of_uncached<'tcx>(
|
||||
};
|
||||
|
||||
// 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 size = size.align_to(align.abi);
|
||||
|
||||
@ -438,11 +454,12 @@ fn layout_of_uncached<'tcx>(
|
||||
tcx.def_span(def.did()),
|
||||
"union cannot be packed and aligned",
|
||||
);
|
||||
return Err(LayoutError::Unknown(ty));
|
||||
return Err(error(cx, LayoutError::Unknown(ty)));
|
||||
}
|
||||
|
||||
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(..) => {
|
||||
// NOTE(eddyb) `layout_of` query should've normalized these away,
|
||||
// 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(_) => {
|
||||
@ -492,7 +509,7 @@ fn layout_of_uncached<'tcx>(
|
||||
}
|
||||
|
||||
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>,
|
||||
def_id: hir::def_id::DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> Result<Layout<'tcx>, LayoutError<'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 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);
|
||||
|
||||
|
@ -17,7 +17,7 @@ use crate::html::render::Context;
|
||||
#[template(path = "type_layout.html")]
|
||||
struct TypeLayout<'cx> {
|
||||
variants: Vec<(Symbol, TypeLayoutSize)>,
|
||||
type_layout_size: Result<TypeLayoutSize, LayoutError<'cx>>,
|
||||
type_layout_size: Result<TypeLayoutSize, &'cx LayoutError<'cx>>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
|
@ -311,7 +311,7 @@ pub struct 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 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 });
|
||||
|
Loading…
Reference in New Issue
Block a user