Skip to content

File tree

13 files changed

+108
-80
lines changed

13 files changed

+108
-80
lines changed
 

‎compiler/rustc_const_eval/src/interpret/intrinsics.rs

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

‎compiler/rustc_const_eval/src/util/check_validity_requirement.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub fn check_validity_requirement<'tcx>(
2121
tcx: TyCtxt<'tcx>,
2222
kind: ValidityRequirement,
2323
param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
24-
) -> Result<bool, LayoutError<'tcx>> {
24+
) -> Result<bool, &'tcx LayoutError<'tcx>> {
2525
let layout = tcx.layout_of(param_env_and_ty)?;
2626

2727
// There is nothing strict or lax about inhabitedness.
@@ -43,7 +43,7 @@ fn might_permit_raw_init_strict<'tcx>(
4343
ty: TyAndLayout<'tcx>,
4444
tcx: TyCtxt<'tcx>,
4545
kind: ValidityRequirement,
46-
) -> Result<bool, LayoutError<'tcx>> {
46+
) -> Result<bool, &'tcx LayoutError<'tcx>> {
4747
let machine = CompileTimeInterpreter::new(CanAccessStatics::No, CheckAlignment::Error);
4848

4949
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>(
7575
this: TyAndLayout<'tcx>,
7676
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
7777
init_kind: ValidityRequirement,
78-
) -> Result<bool, LayoutError<'tcx>> {
78+
) -> Result<bool, &'tcx LayoutError<'tcx>> {
7979
let scalar_allows_raw_init = move |s: Scalar| -> bool {
8080
match init_kind {
8181
ValidityRequirement::Inhabited => {

‎compiler/rustc_hir_typeck/src/intrinsicck.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8181
}
8282

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

‎compiler/rustc_middle/src/query/erase.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ impl<T> EraseType for Result<&'_ T, traits::CodegenObligationError> {
7171
type Result = [u8; size_of::<Result<&'static (), traits::CodegenObligationError>>()];
7272
}
7373

74-
impl<T> EraseType for Result<&'_ T, ty::layout::FnAbiError<'_>> {
75-
type Result = [u8; size_of::<Result<&'static (), ty::layout::FnAbiError<'static>>>()];
74+
impl<T> EraseType for Result<&'_ T, &'_ ty::layout::FnAbiError<'_>> {
75+
type Result = [u8; size_of::<Result<&'static (), &'static ty::layout::FnAbiError<'static>>>()];
7676
}
7777

7878
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> {
9696
type Result = [u8; size_of::<Result<ty::GenericArg<'static>, traits::query::NoSolution>>()];
9797
}
9898

99-
impl EraseType for Result<bool, ty::layout::LayoutError<'_>> {
100-
type Result = [u8; size_of::<Result<bool, ty::layout::LayoutError<'static>>>()];
99+
impl EraseType for Result<bool, &ty::layout::LayoutError<'_>> {
100+
type Result = [u8; size_of::<Result<bool, &'static ty::layout::LayoutError<'static>>>()];
101101
}
102102

103-
impl EraseType for Result<rustc_target::abi::TyAndLayout<'_, Ty<'_>>, ty::layout::LayoutError<'_>> {
103+
impl EraseType
104+
for Result<rustc_target::abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::LayoutError<'_>>
105+
{
104106
type Result = [u8; size_of::<
105107
Result<
106108
rustc_target::abi::TyAndLayout<'static, Ty<'static>>,
107-
ty::layout::LayoutError<'static>,
109+
&'static ty::layout::LayoutError<'static>,
108110
>,
109111
>()];
110112
}

‎compiler/rustc_middle/src/query/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,7 @@ rustc_queries! {
13831383
/// executes in "reveal all" mode, and will normalize the input type.
13841384
query layout_of(
13851385
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
1386-
) -> Result<ty::layout::TyAndLayout<'tcx>, ty::layout::LayoutError<'tcx>> {
1386+
) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
13871387
depth_limit
13881388
desc { "computing layout of `{}`", key.value }
13891389
}
@@ -1394,7 +1394,7 @@ rustc_queries! {
13941394
/// instead, where the instance is an `InstanceDef::Virtual`.
13951395
query fn_abi_of_fn_ptr(
13961396
key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
1397-
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
1397+
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
13981398
desc { "computing call ABI of `{}` function pointers", key.value.0 }
13991399
}
14001400

@@ -1405,7 +1405,7 @@ rustc_queries! {
14051405
/// to an `InstanceDef::Virtual` instance (of `<dyn Trait as Trait>::fn`).
14061406
query fn_abi_of_instance(
14071407
key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
1408-
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
1408+
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
14091409
desc { "computing call ABI of `{}`", key.value.0 }
14101410
}
14111411

@@ -2164,7 +2164,7 @@ rustc_queries! {
21642164
separate_provide_extern
21652165
}
21662166

2167-
query check_validity_requirement(key: (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>)) -> Result<bool, ty::layout::LayoutError<'tcx>> {
2167+
query check_validity_requirement(key: (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>)) -> Result<bool, &'tcx ty::layout::LayoutError<'tcx>> {
21682168
desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 }
21692169
}
21702170

‎compiler/rustc_middle/src/ty/layout.rs

+27-25
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
310310
ty: Ty<'tcx>,
311311
tcx: TyCtxt<'tcx>,
312312
param_env: ty::ParamEnv<'tcx>,
313-
) -> Result<SizeSkeleton<'tcx>, LayoutError<'tcx>> {
313+
) -> Result<SizeSkeleton<'tcx>, &'tcx LayoutError<'tcx>> {
314314
debug_assert!(!ty.has_non_region_infer());
315315

316316
// First try computing a static layout.
@@ -353,21 +353,21 @@ impl<'tcx> SizeSkeleton<'tcx> {
353353
let size = s
354354
.bytes()
355355
.checked_mul(c)
356-
.ok_or_else(|| LayoutError::SizeOverflow(ty))?;
356+
.ok_or_else(|| &*tcx.arena.alloc(LayoutError::SizeOverflow(ty)))?;
357357
return Ok(SizeSkeleton::Known(Size::from_bytes(size)));
358358
}
359359
let len = tcx.expand_abstract_consts(len);
360360
let prev = ty::Const::from_target_usize(tcx, s.bytes());
361361
let Some(gen_size) = mul_sorted_consts(tcx, param_env, len, prev) else {
362-
return Err(LayoutError::SizeOverflow(ty));
362+
return Err(tcx.arena.alloc(LayoutError::SizeOverflow(ty)));
363363
};
364364
Ok(SizeSkeleton::Generic(gen_size))
365365
}
366366
SizeSkeleton::Pointer { .. } => Err(err),
367367
SizeSkeleton::Generic(g) => {
368368
let len = tcx.expand_abstract_consts(len);
369369
let Some(gen_size) = mul_sorted_consts(tcx, param_env, len, g) else {
370-
return Err(LayoutError::SizeOverflow(ty));
370+
return Err(tcx.arena.alloc(LayoutError::SizeOverflow(ty)));
371371
};
372372
Ok(SizeSkeleton::Generic(gen_size))
373373
}
@@ -672,33 +672,43 @@ pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> {
672672

673673
MaybeResult::from(
674674
tcx.layout_of(self.param_env().and(ty))
675-
.map_err(|err| self.handle_layout_err(err, span, ty)),
675+
.map_err(|err| self.handle_layout_err(*err, span, ty)),
676676
)
677677
}
678678
}
679679

680680
impl<'tcx, C: LayoutOfHelpers<'tcx>> LayoutOf<'tcx> for C {}
681681

682682
impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxt<'tcx>> {
683-
type LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;
683+
type LayoutOfResult = Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>>;
684684

685685
#[inline]
686-
fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> LayoutError<'tcx> {
687-
err
686+
fn handle_layout_err(
687+
&self,
688+
err: LayoutError<'tcx>,
689+
_: Span,
690+
_: Ty<'tcx>,
691+
) -> &'tcx LayoutError<'tcx> {
692+
self.tcx.arena.alloc(err)
688693
}
689694
}
690695

691696
impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxtAt<'tcx>> {
692-
type LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;
697+
type LayoutOfResult = Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>>;
693698

694699
#[inline]
695700
fn layout_tcx_at_span(&self) -> Span {
696701
self.tcx.span
697702
}
698703

699704
#[inline]
700-
fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> LayoutError<'tcx> {
701-
err
705+
fn handle_layout_err(
706+
&self,
707+
err: LayoutError<'tcx>,
708+
_: Span,
709+
_: Ty<'tcx>,
710+
) -> &'tcx LayoutError<'tcx> {
711+
self.tcx.arena.alloc(err)
702712
}
703713
}
704714

@@ -1250,18 +1260,6 @@ pub enum FnAbiError<'tcx> {
12501260
AdjustForForeignAbi(call::AdjustForForeignAbiError),
12511261
}
12521262

1253-
impl<'tcx> From<LayoutError<'tcx>> for FnAbiError<'tcx> {
1254-
fn from(err: LayoutError<'tcx>) -> Self {
1255-
Self::Layout(err)
1256-
}
1257-
}
1258-
1259-
impl From<call::AdjustForForeignAbiError> for FnAbiError<'_> {
1260-
fn from(err: call::AdjustForForeignAbiError) -> Self {
1261-
Self::AdjustForForeignAbi(err)
1262-
}
1263-
}
1264-
12651263
impl<'a, 'b> IntoDiagnostic<'a, !> for FnAbiError<'b> {
12661264
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, !> {
12671265
match self {
@@ -1321,7 +1319,7 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
13211319
let tcx = self.tcx().at(span);
13221320

13231321
MaybeResult::from(tcx.fn_abi_of_fn_ptr(self.param_env().and((sig, extra_args))).map_err(
1324-
|err| self.handle_fn_abi_err(err, span, FnAbiRequest::OfFnPtr { sig, extra_args }),
1322+
|err| self.handle_fn_abi_err(*err, span, FnAbiRequest::OfFnPtr { sig, extra_args }),
13251323
))
13261324
}
13271325

@@ -1348,7 +1346,11 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
13481346
// However, we don't do this early in order to avoid calling
13491347
// `def_span` unconditionally (which may have a perf penalty).
13501348
let span = if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) };
1351-
self.handle_fn_abi_err(err, span, FnAbiRequest::OfInstance { instance, extra_args })
1349+
self.handle_fn_abi_err(
1350+
*err,
1351+
span,
1352+
FnAbiRequest::OfInstance { instance, extra_args },
1353+
)
13521354
}),
13531355
)
13541356
}

‎compiler/rustc_middle/src/values.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,12 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::EarlyBinder<ty::Binder<'_, ty::F
106106
}
107107
}
108108

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

‎compiler/rustc_passes/src/layout_test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
9494
Err(layout_error) => {
9595
tcx.sess.emit_fatal(Spanned {
9696
node: layout_error.into_diagnostic(),
97+
9798
span: tcx.def_span(item_def_id.to_def_id()),
9899
});
99100
}

‎compiler/rustc_transmute/src/layout/tree.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ pub(crate) mod rustc {
192192
TypeError(ErrorGuaranteed),
193193
}
194194

195-
impl<'tcx> From<LayoutError<'tcx>> for Err {
196-
fn from(err: LayoutError<'tcx>) -> Self {
195+
impl<'tcx> From<&LayoutError<'tcx>> for Err {
196+
fn from(err: &LayoutError<'tcx>) -> Self {
197197
match err {
198198
LayoutError::Unknown(..) => Self::UnknownLayout,
199199
err => unimplemented!("{:?}", err),
@@ -221,7 +221,7 @@ pub(crate) mod rustc {
221221
}
222222

223223
impl LayoutSummary {
224-
fn from_ty<'tcx>(ty: Ty<'tcx>, ctx: TyCtxt<'tcx>) -> Result<Self, LayoutError<'tcx>> {
224+
fn from_ty<'tcx>(ty: Ty<'tcx>, ctx: TyCtxt<'tcx>) -> Result<Self, &'tcx LayoutError<'tcx>> {
225225
use rustc_middle::ty::ParamEnvAnd;
226226
use rustc_target::abi::{TyAndLayout, Variants};
227227

@@ -482,7 +482,7 @@ pub(crate) mod rustc {
482482
fn layout_of<'tcx>(
483483
ctx: TyCtxt<'tcx>,
484484
ty: Ty<'tcx>,
485-
) -> Result<alloc::Layout, LayoutError<'tcx>> {
485+
) -> Result<alloc::Layout, &'tcx LayoutError<'tcx>> {
486486
use rustc_middle::ty::ParamEnvAnd;
487487
use rustc_target::abi::TyAndLayout;
488488

‎compiler/rustc_ty_utils/src/abi.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
202202
fn fn_abi_of_fn_ptr<'tcx>(
203203
tcx: TyCtxt<'tcx>,
204204
query: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
205-
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
205+
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
206206
let (param_env, (sig, extra_args)) = query.into_parts();
207207

208208
let cx = LayoutCx { tcx, param_env };
@@ -212,7 +212,7 @@ fn fn_abi_of_fn_ptr<'tcx>(
212212
fn fn_abi_of_instance<'tcx>(
213213
tcx: TyCtxt<'tcx>,
214214
query: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
215-
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
215+
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
216216
let (param_env, (instance, extra_args)) = query.into_parts();
217217

218218
let sig = fn_sig_for_fn_abi(tcx, instance, param_env);
@@ -331,7 +331,7 @@ fn fn_abi_new_uncached<'tcx>(
331331
fn_def_id: Option<DefId>,
332332
// FIXME(eddyb) replace this with something typed, like an `enum`.
333333
force_thin_self_ptr: bool,
334-
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
334+
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
335335
let sig = cx.tcx.normalize_erasing_late_bound_regions(cx.param_env, sig);
336336

337337
let conv = conv_from_spec_abi(cx.tcx(), sig.abi);
@@ -376,7 +376,7 @@ fn fn_abi_new_uncached<'tcx>(
376376
let is_drop_in_place =
377377
fn_def_id.is_some() && fn_def_id == cx.tcx.lang_items().drop_in_place_fn();
378378

379-
let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, FnAbiError<'tcx>> {
379+
let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, &'tcx FnAbiError<'tcx>> {
380380
let span = tracing::debug_span!("arg_of");
381381
let _entered = span.enter();
382382
let is_return = arg_idx.is_none();
@@ -386,7 +386,8 @@ fn fn_abi_new_uncached<'tcx>(
386386
_ => bug!("argument to drop_in_place is not a raw ptr: {:?}", ty),
387387
});
388388

389-
let layout = cx.layout_of(ty)?;
389+
let layout =
390+
cx.layout_of(ty).map_err(|err| &*cx.tcx.arena.alloc(FnAbiError::Layout(*err)))?;
390391
let layout = if force_thin_self_ptr && arg_idx == Some(0) {
391392
// Don't pass the vtable, it's not an argument of the virtual fn.
392393
// 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>(
454455
fn_abi: &mut FnAbi<'tcx, Ty<'tcx>>,
455456
abi: SpecAbi,
456457
fn_def_id: Option<DefId>,
457-
) -> Result<(), FnAbiError<'tcx>> {
458+
) -> Result<(), &'tcx FnAbiError<'tcx>> {
458459
if abi == SpecAbi::Unadjusted {
459460
return Ok(());
460461
}
@@ -548,7 +549,9 @@ fn fn_abi_adjust_for_abi<'tcx>(
548549
fixup(arg, Some(arg_idx));
549550
}
550551
} else {
551-
fn_abi.adjust_for_foreign_abi(cx, abi)?;
552+
fn_abi
553+
.adjust_for_foreign_abi(cx, abi)
554+
.map_err(|err| &*cx.tcx.arena.alloc(FnAbiError::AdjustForForeignAbi(err)))?;
552555
}
553556

554557
Ok(())

‎compiler/rustc_ty_utils/src/layout.rs

+41-24
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub fn provide(providers: &mut Providers) {
3131
fn layout_of<'tcx>(
3232
tcx: TyCtxt<'tcx>,
3333
query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
34-
) -> Result<TyAndLayout<'tcx>, LayoutError<'tcx>> {
34+
) -> Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>> {
3535
let (param_env, ty) = query.into_parts();
3636
debug!(?ty);
3737

@@ -45,7 +45,9 @@ fn layout_of<'tcx>(
4545
let ty = match tcx.try_normalize_erasing_regions(param_env, ty) {
4646
Ok(t) => t,
4747
Err(normalization_error) => {
48-
return Err(LayoutError::NormalizationFailure(ty, normalization_error));
48+
return Err(tcx
49+
.arena
50+
.alloc(LayoutError::NormalizationFailure(ty, normalization_error)));
4951
}
5052
};
5153

@@ -66,27 +68,34 @@ fn layout_of<'tcx>(
6668
Ok(layout)
6769
}
6870

71+
fn error<'tcx>(
72+
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
73+
err: LayoutError<'tcx>,
74+
) -> &'tcx LayoutError<'tcx> {
75+
cx.tcx.arena.alloc(err)
76+
}
77+
6978
fn univariant_uninterned<'tcx>(
7079
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
7180
ty: Ty<'tcx>,
7281
fields: &IndexSlice<FieldIdx, Layout<'_>>,
7382
repr: &ReprOptions,
7483
kind: StructKind,
75-
) -> Result<LayoutS, LayoutError<'tcx>> {
84+
) -> Result<LayoutS, &'tcx LayoutError<'tcx>> {
7685
let dl = cx.data_layout();
7786
let pack = repr.pack;
7887
if pack.is_some() && repr.align.is_some() {
7988
cx.tcx.sess.delay_span_bug(DUMMY_SP, "struct cannot be packed and aligned");
80-
return Err(LayoutError::Unknown(ty));
89+
return Err(cx.tcx.arena.alloc(LayoutError::Unknown(ty)));
8190
}
8291

83-
cx.univariant(dl, fields, repr, kind).ok_or(LayoutError::SizeOverflow(ty))
92+
cx.univariant(dl, fields, repr, kind).ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))
8493
}
8594

8695
fn layout_of_uncached<'tcx>(
8796
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
8897
ty: Ty<'tcx>,
89-
) -> Result<Layout<'tcx>, LayoutError<'tcx>> {
98+
) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> {
9099
let tcx = cx.tcx;
91100
let param_env = cx.param_env;
92101
let dl = cx.data_layout();
@@ -170,7 +179,7 @@ fn layout_of_uncached<'tcx>(
170179
err = better_err;
171180
}
172181
}
173-
return Err(LayoutError::NormalizationFailure(pointee, err));
182+
return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
174183
},
175184
};
176185

@@ -181,7 +190,7 @@ fn layout_of_uncached<'tcx>(
181190
}
182191

183192
let Abi::Scalar(metadata) = metadata_layout.abi else {
184-
return Err(LayoutError::Unknown(pointee));
193+
return Err(error(cx, LayoutError::Unknown(pointee)));
185194
};
186195

187196
metadata
@@ -199,7 +208,7 @@ fn layout_of_uncached<'tcx>(
199208
vtable
200209
}
201210
_ => {
202-
return Err(LayoutError::Unknown(pointee));
211+
return Err(error(cx, LayoutError::Unknown(pointee)));
203212
}
204213
}
205214
};
@@ -221,14 +230,18 @@ fn layout_of_uncached<'tcx>(
221230
if count.has_projections() {
222231
count = tcx.normalize_erasing_regions(param_env, count);
223232
if count.has_projections() {
224-
return Err(LayoutError::Unknown(ty));
233+
return Err(error(cx, LayoutError::Unknown(ty)));
225234
}
226235
}
227236

228-
let count =
229-
count.try_eval_target_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?;
237+
let count = count
238+
.try_eval_target_usize(tcx, param_env)
239+
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
230240
let element = cx.layout_of(element)?;
231-
let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?;
241+
let size = element
242+
.size
243+
.checked_mul(count, dl)
244+
.ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?;
232245

233246
let abi = if count != 0 && ty.is_privately_uninhabited(tcx, param_env) {
234247
Abi::Uninhabited
@@ -316,7 +329,7 @@ fn layout_of_uncached<'tcx>(
316329
DUMMY_SP,
317330
"#[repr(simd)] was applied to an ADT that is not a struct",
318331
);
319-
return Err(LayoutError::Unknown(ty));
332+
return Err(error(cx, LayoutError::Unknown(ty)));
320333
}
321334

322335
let fields = &def.non_enum_variant().fields;
@@ -346,7 +359,7 @@ fn layout_of_uncached<'tcx>(
346359
DUMMY_SP,
347360
"#[repr(simd)] was applied to an ADT with heterogeneous field type",
348361
);
349-
return Err(LayoutError::Unknown(ty));
362+
return Err(error(cx, LayoutError::Unknown(ty)));
350363
}
351364
}
352365

@@ -368,7 +381,7 @@ fn layout_of_uncached<'tcx>(
368381

369382
// Extract the number of elements from the layout of the array field:
370383
let FieldsShape::Array { count, .. } = cx.layout_of(f0_ty)?.layout.fields() else {
371-
return Err(LayoutError::Unknown(ty));
384+
return Err(error(cx, LayoutError::Unknown(ty)));
372385
};
373386

374387
(*e_ty, *count, true)
@@ -397,7 +410,10 @@ fn layout_of_uncached<'tcx>(
397410
};
398411

399412
// Compute the size and alignment of the vector:
400-
let size = e_ly.size.checked_mul(e_len, dl).ok_or(LayoutError::SizeOverflow(ty))?;
413+
let size = e_ly
414+
.size
415+
.checked_mul(e_len, dl)
416+
.ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?;
401417
let align = dl.vector_align(size);
402418
let size = size.align_to(align.abi);
403419

@@ -438,11 +454,12 @@ fn layout_of_uncached<'tcx>(
438454
tcx.def_span(def.did()),
439455
"union cannot be packed and aligned",
440456
);
441-
return Err(LayoutError::Unknown(ty));
457+
return Err(error(cx, LayoutError::Unknown(ty)));
442458
}
443459

444460
return Ok(tcx.mk_layout(
445-
cx.layout_of_union(&def.repr(), &variants).ok_or(LayoutError::Unknown(ty))?,
461+
cx.layout_of_union(&def.repr(), &variants)
462+
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?,
446463
));
447464
}
448465

@@ -476,23 +493,23 @@ fn layout_of_uncached<'tcx>(
476493
}
477494
},
478495
)
479-
.ok_or(LayoutError::SizeOverflow(ty))?,
496+
.ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?,
480497
)
481498
}
482499

483500
// Types with no meaningful known layout.
484501
ty::Alias(..) => {
485502
// NOTE(eddyb) `layout_of` query should've normalized these away,
486503
// if that was possible, so there's no reason to try again here.
487-
return Err(LayoutError::Unknown(ty));
504+
return Err(error(cx, LayoutError::Unknown(ty)));
488505
}
489506

490507
ty::Bound(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) | ty::Infer(_) => {
491508
bug!("Layout::compute: unexpected type `{}`", ty)
492509
}
493510

494511
ty::Placeholder(..) | ty::Param(_) | ty::Error(_) => {
495-
return Err(LayoutError::Unknown(ty));
512+
return Err(error(cx, LayoutError::Unknown(ty)));
496513
}
497514
})
498515
}
@@ -628,13 +645,13 @@ fn generator_layout<'tcx>(
628645
ty: Ty<'tcx>,
629646
def_id: hir::def_id::DefId,
630647
substs: SubstsRef<'tcx>,
631-
) -> Result<Layout<'tcx>, LayoutError<'tcx>> {
648+
) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> {
632649
use SavedLocalEligibility::*;
633650
let tcx = cx.tcx;
634651
let subst_field = |ty: Ty<'tcx>| EarlyBinder::bind(ty).subst(tcx, substs);
635652

636653
let Some(info) = tcx.generator_layout(def_id) else {
637-
return Err(LayoutError::Unknown(ty));
654+
return Err(error(cx, LayoutError::Unknown(ty)));
638655
};
639656
let (ineligible_locals, assignments) = generator_saved_local_eligibility(&info);
640657

‎src/librustdoc/html/render/type_layout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::html::render::Context;
1717
#[template(path = "type_layout.html")]
1818
struct TypeLayout<'cx> {
1919
variants: Vec<(Symbol, TypeLayoutSize)>,
20-
type_layout_size: Result<TypeLayoutSize, LayoutError<'cx>>,
20+
type_layout_size: Result<TypeLayoutSize, &'cx LayoutError<'cx>>,
2121
}
2222

2323
#[derive(Template)]

‎src/tools/miri/src/machine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ pub struct PrimitiveLayouts<'tcx> {
311311
}
312312

313313
impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
314-
fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, LayoutError<'tcx>> {
314+
fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, &'tcx LayoutError<'tcx>> {
315315
let tcx = layout_cx.tcx;
316316
let mut_raw_ptr = tcx.mk_ptr(TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Mut });
317317
let const_raw_ptr = tcx.mk_ptr(TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Not });

0 commit comments

Comments
 (0)
Please sign in to comment.