Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shrink error variants for layout and fn_abi #111035

Merged
merged 2 commits into from
Jul 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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);
Expand Down Expand Up @@ -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 => {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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}")
Expand Down
14 changes: 8 additions & 6 deletions compiler/rustc_middle/src/query/erase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand All @@ -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>,
>,
>()];
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}
Expand All @@ -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 }
}

Expand All @@ -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 }
}

Expand Down Expand Up @@ -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 }
}

Expand Down
52 changes: 27 additions & 25 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -353,21 +353,21 @@ 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))
}
SizeSkeleton::Pointer { .. } => Err(err),
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))
}
Expand Down Expand Up @@ -672,33 +672,43 @@ 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)),
)
}
}

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 {
self.tcx.span
}

#[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)
}
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 }),
))
}

Expand All @@ -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 },
)
}),
)
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_middle/src/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_passes/src/layout_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
});
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_transmute/src/layout/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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};

Expand Down Expand Up @@ -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;

Expand Down
17 changes: 10 additions & 7 deletions compiler/rustc_ty_utils/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand All @@ -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`
Expand Down Expand Up @@ -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(());
}
Expand Down Expand Up @@ -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(())
Expand Down
Loading