diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index fd05664e2f227..6686413bf0254 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -11,7 +11,8 @@ use rustc_span::{Span, Symbol}; use super::CompileTimeMachine; use crate::errors::{self, FrameNote, ReportErrorExt}; use crate::interpret::{ - ErrorHandled, Frame, InterpError, InterpErrorInfo, MachineStopType, err_inval, err_machine_stop, + ErrorHandled, Frame, InterpErrorInfo, InterpErrorKind, MachineStopType, err_inval, + err_machine_stop, }; /// The CTFE machine has some custom error kinds. @@ -57,7 +58,7 @@ impl MachineStopType for ConstEvalErrKind { } } -/// The errors become [`InterpError::MachineStop`] when being raised. +/// The errors become [`InterpErrorKind::MachineStop`] when being raised. impl<'tcx> Into> for ConstEvalErrKind { fn into(self) -> InterpErrorInfo<'tcx> { err_machine_stop!(self).into() @@ -124,7 +125,7 @@ pub fn get_span_and_frames<'tcx>( /// `get_span_and_frames`. pub(super) fn report<'tcx, C, F, E>( tcx: TyCtxt<'tcx>, - error: InterpError<'tcx>, + error: InterpErrorKind<'tcx>, span: Span, get_span_and_frames: C, mk: F, diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 672353e629d44..7319c251bbd99 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -18,7 +18,7 @@ use tracing::{debug, instrument, trace}; use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine}; use crate::const_eval::CheckAlignment; use crate::interpret::{ - CtfeValidationMode, GlobalId, Immediate, InternKind, InternResult, InterpCx, InterpError, + CtfeValidationMode, GlobalId, Immediate, InternKind, InternResult, InterpCx, InterpErrorKind, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup, create_static_alloc, eval_nullary_intrinsic, intern_const_alloc_recursive, interp_ok, throw_exhaust, }; @@ -463,7 +463,7 @@ fn report_validation_error<'tcx>( error: InterpErrorInfo<'tcx>, alloc_id: AllocId, ) -> ErrorHandled { - if !matches!(error.kind(), InterpError::UndefinedBehavior(_)) { + if !matches!(error.kind(), InterpErrorKind::UndefinedBehavior(_)) { // Some other error happened during validation, e.g. an unsupported operation. return report_eval_error(ecx, cid, error); } diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index c943236affc56..211668cf055c6 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -9,7 +9,7 @@ use rustc_errors::{ use rustc_hir::ConstContext; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::interpret::{ - CheckInAllocMsg, CtfeProvenance, ExpectedKind, InterpError, InvalidMetaKind, + CheckInAllocMsg, CtfeProvenance, ExpectedKind, InterpErrorKind, InvalidMetaKind, InvalidProgramInfo, Misalignment, Pointer, PointerKind, ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, }; @@ -835,23 +835,23 @@ impl ReportErrorExt for UnsupportedOpInfo { } } -impl<'tcx> ReportErrorExt for InterpError<'tcx> { +impl<'tcx> ReportErrorExt for InterpErrorKind<'tcx> { fn diagnostic_message(&self) -> DiagMessage { match self { - InterpError::UndefinedBehavior(ub) => ub.diagnostic_message(), - InterpError::Unsupported(e) => e.diagnostic_message(), - InterpError::InvalidProgram(e) => e.diagnostic_message(), - InterpError::ResourceExhaustion(e) => e.diagnostic_message(), - InterpError::MachineStop(e) => e.diagnostic_message(), + InterpErrorKind::UndefinedBehavior(ub) => ub.diagnostic_message(), + InterpErrorKind::Unsupported(e) => e.diagnostic_message(), + InterpErrorKind::InvalidProgram(e) => e.diagnostic_message(), + InterpErrorKind::ResourceExhaustion(e) => e.diagnostic_message(), + InterpErrorKind::MachineStop(e) => e.diagnostic_message(), } } fn add_args(self, diag: &mut Diag<'_, G>) { match self { - InterpError::UndefinedBehavior(ub) => ub.add_args(diag), - InterpError::Unsupported(e) => e.add_args(diag), - InterpError::InvalidProgram(e) => e.add_args(diag), - InterpError::ResourceExhaustion(e) => e.add_args(diag), - InterpError::MachineStop(e) => e.add_args(&mut |name, value| { + InterpErrorKind::UndefinedBehavior(ub) => ub.add_args(diag), + InterpErrorKind::Unsupported(e) => e.add_args(diag), + InterpErrorKind::InvalidProgram(e) => e.add_args(diag), + InterpErrorKind::ResourceExhaustion(e) => e.add_args(diag), + InterpErrorKind::MachineStop(e) => e.add_args(&mut |name, value| { diag.arg(name, value); }), } diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 4945563f4a4ee..85d99900c6ccd 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -471,7 +471,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Don't forget to mark "initially live" locals as live. self.storage_live_for_always_live_locals()?; }; - res.inspect_err(|_| { + res.inspect_err_kind(|_| { // Don't show the incomplete stack frame in the error stacktrace. self.stack_mut().pop(); }) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 02dd7821ef667..a1c773a4b8005 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -19,7 +19,7 @@ use rustc_trait_selection::traits::ObligationCtxt; use tracing::{debug, instrument, trace}; use super::{ - Frame, FrameInfo, GlobalId, InterpError, InterpErrorInfo, InterpResult, MPlaceTy, Machine, + Frame, FrameInfo, GlobalId, InterpErrorInfo, InterpErrorKind, InterpResult, MPlaceTy, Machine, MemPlaceMeta, Memory, OpTy, Place, PlaceTy, PointerArithmetic, Projectable, Provenance, err_inval, interp_ok, throw_inval, throw_ub, throw_ub_custom, }; @@ -73,7 +73,7 @@ where } impl<'tcx, M: Machine<'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'tcx, M> { - type LayoutOfResult = Result, InterpError<'tcx>>; + type LayoutOfResult = Result, InterpErrorKind<'tcx>>; #[inline] fn layout_tcx_at_span(&self) -> Span { @@ -82,20 +82,25 @@ impl<'tcx, M: Machine<'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'tcx, M> { } #[inline] - fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> InterpError<'tcx> { + fn handle_layout_err( + &self, + err: LayoutError<'tcx>, + _: Span, + _: Ty<'tcx>, + ) -> InterpErrorKind<'tcx> { err_inval!(Layout(err)) } } impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> { - type FnAbiOfResult = Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, InterpError<'tcx>>; + type FnAbiOfResult = Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, InterpErrorKind<'tcx>>; fn handle_fn_abi_err( &self, err: FnAbiError<'tcx>, _span: Span, _fn_abi_request: FnAbiRequest<'tcx>, - ) -> InterpError<'tcx> { + ) -> InterpErrorKind<'tcx> { match err { FnAbiError::Layout(err) => err_inval!(Layout(err)), FnAbiError::AdjustForForeignAbi(err) => { diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 540898ec6456c..4e603f57c56fb 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -324,13 +324,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { dist.checked_neg().unwrap(), // i64::MIN is impossible as no allocation can be that large CheckInAllocMsg::OffsetFromTest, ) - .map_err(|_| { + .map_err_kind(|_| { // Make the error more specific. err_ub_custom!( fluent::const_eval_offset_from_different_allocations, name = intrinsic_name, ) - .into() })?; // Perform division by size to compute return value. diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 13641ef2bd3f6..b6120ce82fe5f 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -17,8 +17,8 @@ use rustc_hir as hir; use rustc_middle::bug; use rustc_middle::mir::interpret::ValidationErrorKind::{self, *}; use rustc_middle::mir::interpret::{ - ExpectedKind, InterpError, InterpErrorInfo, InvalidMetaKind, Misalignment, PointerKind, - Provenance, UnsupportedOpInfo, ValidationErrorInfo, alloc_range, interp_ok, + ExpectedKind, InterpErrorKind, InvalidMetaKind, Misalignment, PointerKind, Provenance, + UnsupportedOpInfo, ValidationErrorInfo, alloc_range, interp_ok, }; use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Ty}; @@ -37,8 +37,8 @@ use super::{ // for the validation errors #[rustfmt::skip] -use super::InterpError::UndefinedBehavior as Ub; -use super::InterpError::Unsupported as Unsup; +use super::InterpErrorKind::UndefinedBehavior as Ub; +use super::InterpErrorKind::Unsupported as Unsup; use super::UndefinedBehaviorInfo::*; use super::UnsupportedOpInfo::*; @@ -97,20 +97,19 @@ macro_rules! try_validation { ($e:expr, $where:expr, $( $( $p:pat_param )|+ => $kind: expr ),+ $(,)? ) => {{ - $e.map_err(|e| { + $e.map_err_kind(|e| { // We catch the error and turn it into a validation failure. We are okay with // allocation here as this can only slow down builds that fail anyway. - let (kind, backtrace) = e.into_parts(); - match kind { + match e { $( $($p)|+ => { err_validation_failure!( $where, $kind - ).into() + ) } ),+, - _ => InterpErrorInfo::from_parts(kind, backtrace), + e => e, } })? }}; @@ -1230,11 +1229,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, // No need for an alignment check here, this is not an actual memory access. let alloc = self.ecx.get_ptr_alloc(mplace.ptr(), size)?.expect("we already excluded size 0"); - alloc.get_bytes_strip_provenance().map_err(|err| { + alloc.get_bytes_strip_provenance().map_err_kind(|kind| { // Some error happened, try to provide a more detailed description. // For some errors we might be able to provide extra information. // (This custom logic does not fit the `try_validation!` macro.) - let (kind, backtrace) = err.into_parts(); match kind { Ub(InvalidUninitBytes(Some((_alloc_id, access)))) | Unsup(ReadPointerAsInt(Some((_alloc_id, access)))) => { // Some byte was uninitialized, determine which @@ -1247,14 +1245,14 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, self.path.push(PathElem::ArrayElem(i)); if matches!(kind, Ub(InvalidUninitBytes(_))) { - err_validation_failure!(self.path, Uninit { expected }).into() + err_validation_failure!(self.path, Uninit { expected }) } else { - err_validation_failure!(self.path, PointerAsInt { expected }).into() + err_validation_failure!(self.path, PointerAsInt { expected }) } } // Propagate upwards (that will also check for unexpected errors). - _ => return InterpErrorInfo::from_parts(kind, backtrace), + err => err, } })?; @@ -1368,12 +1366,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { v.reset_padding(val)?; interp_ok(()) }) - .map_err(|err| { + .map_err_info(|err| { if !matches!( err.kind(), err_ub!(ValidationError { .. }) - | InterpError::InvalidProgram(_) - | InterpError::Unsupported(UnsupportedOpInfo::ExternTypeField) + | InterpErrorKind::InvalidProgram(_) + | InterpErrorKind::Unsupported(UnsupportedOpInfo::ExternTypeField) ) { bug!( "Unexpected error during validation: {}", diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 04d035e27ba3e..ac3baf74ca7c4 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -18,9 +18,9 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_target::abi::{Align, HasDataLayout, Size}; use super::{ - AllocId, BadBytesAccess, CtfeProvenance, InterpError, InterpResult, Pointer, PointerArithmetic, - Provenance, ResourceExhaustionInfo, Scalar, ScalarSizeMismatch, UndefinedBehaviorInfo, - UnsupportedOpInfo, interp_ok, read_target_uint, write_target_uint, + AllocId, BadBytesAccess, CtfeProvenance, InterpErrorKind, InterpResult, Pointer, + PointerArithmetic, Provenance, ResourceExhaustionInfo, Scalar, ScalarSizeMismatch, + UndefinedBehaviorInfo, UnsupportedOpInfo, interp_ok, read_target_uint, write_target_uint, }; use crate::ty; @@ -199,22 +199,22 @@ impl From for AllocError { } impl AllocError { - pub fn to_interp_error<'tcx>(self, alloc_id: AllocId) -> InterpError<'tcx> { + pub fn to_interp_error<'tcx>(self, alloc_id: AllocId) -> InterpErrorKind<'tcx> { use AllocError::*; match self { ScalarSizeMismatch(s) => { - InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ScalarSizeMismatch(s)) + InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ScalarSizeMismatch(s)) } - ReadPointerAsInt(info) => InterpError::Unsupported( + ReadPointerAsInt(info) => InterpErrorKind::Unsupported( UnsupportedOpInfo::ReadPointerAsInt(info.map(|b| (alloc_id, b))), ), - OverwritePartialPointer(offset) => InterpError::Unsupported( + OverwritePartialPointer(offset) => InterpErrorKind::Unsupported( UnsupportedOpInfo::OverwritePartialPointer(Pointer::new(alloc_id, offset)), ), - ReadPartialPointer(offset) => InterpError::Unsupported( + ReadPartialPointer(offset) => InterpErrorKind::Unsupported( UnsupportedOpInfo::ReadPartialPointer(Pointer::new(alloc_id, offset)), ), - InvalidUninitBytes(info) => InterpError::UndefinedBehavior( + InvalidUninitBytes(info) => InterpErrorKind::UndefinedBehavior( UndefinedBehaviorInfo::InvalidUninitBytes(info.map(|b| (alloc_id, b))), ), } @@ -318,7 +318,7 @@ impl Allocation { pub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self> { Self::uninit_inner(size, align, || { ty::tls::with(|tcx| tcx.dcx().delayed_bug("exhausted memory during interpretation")); - InterpError::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted) + InterpErrorKind::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted) }) .into() } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index fcb87e1943505..b520f21ce20c9 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -113,7 +113,7 @@ pub struct InterpErrorInfo<'tcx>(Box>); #[derive(Debug)] struct InterpErrorInfoInner<'tcx> { - kind: InterpError<'tcx>, + kind: InterpErrorKind<'tcx>, backtrace: InterpErrorBacktrace, } @@ -154,21 +154,21 @@ impl InterpErrorBacktrace { } impl<'tcx> InterpErrorInfo<'tcx> { - pub fn into_parts(self) -> (InterpError<'tcx>, InterpErrorBacktrace) { + pub fn into_parts(self) -> (InterpErrorKind<'tcx>, InterpErrorBacktrace) { let InterpErrorInfo(box InterpErrorInfoInner { kind, backtrace }) = self; (kind, backtrace) } - pub fn into_kind(self) -> InterpError<'tcx> { + pub fn into_kind(self) -> InterpErrorKind<'tcx> { self.0.kind } - pub fn from_parts(kind: InterpError<'tcx>, backtrace: InterpErrorBacktrace) -> Self { + pub fn from_parts(kind: InterpErrorKind<'tcx>, backtrace: InterpErrorBacktrace) -> Self { Self(Box::new(InterpErrorInfoInner { kind, backtrace })) } #[inline] - pub fn kind(&self) -> &InterpError<'tcx> { + pub fn kind(&self) -> &InterpErrorKind<'tcx> { &self.0.kind } } @@ -179,13 +179,13 @@ fn print_backtrace(backtrace: &Backtrace) { impl From for InterpErrorInfo<'_> { fn from(err: ErrorGuaranteed) -> Self { - InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err.into())).into() + InterpErrorKind::InvalidProgram(InvalidProgramInfo::AlreadyReported(err.into())).into() } } impl From for InterpErrorInfo<'_> { fn from(err: ErrorHandled) -> Self { - InterpError::InvalidProgram(match err { + InterpErrorKind::InvalidProgram(match err { ErrorHandled::Reported(r, _span) => InvalidProgramInfo::AlreadyReported(r), ErrorHandled::TooGeneric(_span) => InvalidProgramInfo::TooGeneric, }) @@ -193,8 +193,8 @@ impl From for InterpErrorInfo<'_> { } } -impl<'tcx> From> for InterpErrorInfo<'tcx> { - fn from(kind: InterpError<'tcx>) -> Self { +impl<'tcx> From> for InterpErrorInfo<'tcx> { + fn from(kind: InterpErrorKind<'tcx>) -> Self { InterpErrorInfo(Box::new(InterpErrorInfoInner { kind, backtrace: InterpErrorBacktrace::new(), @@ -590,7 +590,7 @@ impl dyn MachineStopType { } #[derive(Debug)] -pub enum InterpError<'tcx> { +pub enum InterpErrorKind<'tcx> { /// The program caused undefined behavior. UndefinedBehavior(UndefinedBehaviorInfo<'tcx>), /// The program did something the interpreter does not support (some of these *might* be UB @@ -606,25 +606,25 @@ pub enum InterpError<'tcx> { MachineStop(Box), } -impl InterpError<'_> { +impl InterpErrorKind<'_> { /// Some errors do string formatting even if the error is never printed. /// To avoid performance issues, there are places where we want to be sure to never raise these formatting errors, /// so this method lets us detect them and `bug!` on unexpected errors. pub fn formatted_string(&self) -> bool { matches!( self, - InterpError::Unsupported(UnsupportedOpInfo::Unsupported(_)) - | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ValidationError { .. }) - | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::Ub(_)) + InterpErrorKind::Unsupported(UnsupportedOpInfo::Unsupported(_)) + | InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ValidationError { .. }) + | InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::Ub(_)) ) } } -// Macros for constructing / throwing `InterpError` +// Macros for constructing / throwing `InterpErrorKind` #[macro_export] macro_rules! err_unsup { ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::Unsupported( + $crate::mir::interpret::InterpErrorKind::Unsupported( $crate::mir::interpret::UnsupportedOpInfo::$($tt)* ) }; @@ -638,7 +638,7 @@ macro_rules! err_unsup_format { #[macro_export] macro_rules! err_inval { ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::InvalidProgram( + $crate::mir::interpret::InterpErrorKind::InvalidProgram( $crate::mir::interpret::InvalidProgramInfo::$($tt)* ) }; @@ -647,7 +647,7 @@ macro_rules! err_inval { #[macro_export] macro_rules! err_ub { ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::UndefinedBehavior( + $crate::mir::interpret::InterpErrorKind::UndefinedBehavior( $crate::mir::interpret::UndefinedBehaviorInfo::$($tt)* ) }; @@ -680,7 +680,7 @@ macro_rules! err_ub_custom { #[macro_export] macro_rules! err_exhaust { ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::ResourceExhaustion( + $crate::mir::interpret::InterpErrorKind::ResourceExhaustion( $crate::mir::interpret::ResourceExhaustionInfo::$($tt)* ) }; @@ -689,7 +689,7 @@ macro_rules! err_exhaust { #[macro_export] macro_rules! err_machine_stop { ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::MachineStop(Box::new($($tt)*)) + $crate::mir::interpret::InterpErrorKind::MachineStop(Box::new($($tt)*)) }; } @@ -792,9 +792,9 @@ impl<'tcx, T> ops::FromResidual for InterpResult_<'tcx, T> { } // Allow `yeet`ing `InterpError` in functions returning `InterpResult_`. -impl<'tcx, T> ops::FromResidual>> for InterpResult_<'tcx, T> { +impl<'tcx, T> ops::FromResidual>> for InterpResult_<'tcx, T> { #[inline] - fn from_residual(ops::Yeet(e): ops::Yeet>) -> Self { + fn from_residual(ops::Yeet(e): ops::Yeet>) -> Self { Self::new(Err(e.into())) } } @@ -856,7 +856,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> { } #[inline] - pub fn map_err( + pub fn map_err_info( self, f: impl FnOnce(InterpErrorInfo<'tcx>) -> InterpErrorInfo<'tcx>, ) -> InterpResult<'tcx, T> { @@ -864,8 +864,19 @@ impl<'tcx, T> InterpResult_<'tcx, T> { } #[inline] - pub fn inspect_err(self, f: impl FnOnce(&InterpErrorInfo<'tcx>)) -> InterpResult<'tcx, T> { - InterpResult_::new(self.disarm().inspect_err(f)) + pub fn map_err_kind( + self, + f: impl FnOnce(InterpErrorKind<'tcx>) -> InterpErrorKind<'tcx>, + ) -> InterpResult<'tcx, T> { + InterpResult_::new(self.disarm().map_err(|mut e| { + e.0.kind = f(e.0.kind); + e + })) + } + + #[inline] + pub fn inspect_err_kind(self, f: impl FnOnce(&InterpErrorKind<'tcx>)) -> InterpResult<'tcx, T> { + InterpResult_::new(self.disarm().inspect_err(|e| f(&e.0.kind))) } #[inline] diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 115bcdbc58987..790ff3e2fe030 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -36,7 +36,7 @@ pub use self::allocation::{ pub use self::error::{ BadBytesAccess, CheckAlignMsg, CheckInAllocMsg, ErrorHandled, EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, ExpectedKind, - InterpError, InterpErrorInfo, InterpResult, InvalidMetaKind, InvalidProgramInfo, + InterpErrorInfo, InterpErrorKind, InterpResult, InvalidMetaKind, InvalidProgramInfo, MachineStopType, Misalignment, PointerKind, ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind, interp_ok, diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 8f490094d6030..2f97c408f2ae6 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -232,7 +232,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { F: FnOnce(&mut Self) -> InterpResult<'tcx, T>, { f(self) - .map_err(|err| { + .map_err_info(|err| { trace!("InterpCx operation failed: {:?}", err); // Some errors shouldn't come up because creating them causes // an allocation, which we should avoid. When that happens, diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs index 146f9902f6fe0..1684abeec6bfb 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs @@ -13,7 +13,7 @@ fn err_sb_ub<'tcx>( msg: String, help: Vec, history: Option, -) -> InterpError<'tcx> { +) -> InterpErrorKind<'tcx> { err_machine_stop!(TerminationInfo::StackedBorrowsUb { msg, help, history }) } @@ -376,7 +376,7 @@ impl<'history, 'ecx, 'tcx> DiagnosticCx<'history, 'ecx, 'tcx> { /// Report a descriptive error when `new` could not be granted from `derived_from`. #[inline(never)] // This is only called on fatal code paths - pub(super) fn grant_error(&self, stack: &Stack) -> InterpError<'tcx> { + pub(super) fn grant_error(&self, stack: &Stack) -> InterpErrorKind<'tcx> { let Operation::Retag(op) = &self.operation else { unreachable!("grant_error should only be called during a retag") }; @@ -402,7 +402,7 @@ impl<'history, 'ecx, 'tcx> DiagnosticCx<'history, 'ecx, 'tcx> { /// Report a descriptive error when `access` is not permitted based on `tag`. #[inline(never)] // This is only called on fatal code paths - pub(super) fn access_error(&self, stack: &Stack) -> InterpError<'tcx> { + pub(super) fn access_error(&self, stack: &Stack) -> InterpErrorKind<'tcx> { // Deallocation and retagging also do an access as part of their thing, so handle that here, too. let op = match &self.operation { Operation::Access(op) => op, @@ -424,7 +424,7 @@ impl<'history, 'ecx, 'tcx> DiagnosticCx<'history, 'ecx, 'tcx> { } #[inline(never)] // This is only called on fatal code paths - pub(super) fn protector_error(&self, item: &Item, kind: ProtectorKind) -> InterpError<'tcx> { + pub(super) fn protector_error(&self, item: &Item, kind: ProtectorKind) -> InterpErrorKind<'tcx> { let protected = match kind { ProtectorKind::WeakProtector => "weakly protected", ProtectorKind::StrongProtector => "strongly protected", @@ -445,7 +445,7 @@ impl<'history, 'ecx, 'tcx> DiagnosticCx<'history, 'ecx, 'tcx> { } #[inline(never)] // This is only called on fatal code paths - pub fn dealloc_error(&self, stack: &Stack) -> InterpError<'tcx> { + pub fn dealloc_error(&self, stack: &Stack) -> InterpErrorKind<'tcx> { let Operation::Dealloc(op) = &self.operation else { unreachable!("dealloc_error should only be called during a deallocation") }; diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs index cb840f19e3b61..b2fd9b2bf054a 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs @@ -298,7 +298,7 @@ pub(super) struct TbError<'node> { impl TbError<'_> { /// Produce a UB error. - pub fn build<'tcx>(self) -> InterpError<'tcx> { + pub fn build<'tcx>(self) -> InterpErrorKind<'tcx> { use TransitionError::*; let cause = self.access_cause; let accessed = self.accessed_info; diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 15cefab1a68e7..a551b017dfc76 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -674,7 +674,7 @@ impl<'tcx> Tree { Ok(()) } }, - |args: ErrHandlerArgs<'_, TransitionError>| -> InterpError<'tcx> { + |args: ErrHandlerArgs<'_, TransitionError>| -> InterpErrorKind<'tcx> { let ErrHandlerArgs { error_kind, conflicting_info, accessed_info } = args; TbError { conflicting_info, @@ -772,7 +772,7 @@ impl<'tcx> Tree { let err_handler = |perms_range: Range, access_cause: diagnostics::AccessCause, args: ErrHandlerArgs<'_, TransitionError>| - -> InterpError<'tcx> { + -> InterpErrorKind<'tcx> { let ErrHandlerArgs { error_kind, conflicting_info, accessed_info } = args; TbError { conflicting_info, diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 475139a3b5192..f055662891ed6 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -214,7 +214,7 @@ pub fn report_error<'tcx>( ecx: &InterpCx<'tcx, MiriMachine<'tcx>>, e: InterpErrorInfo<'tcx>, ) -> Option<(i64, bool)> { - use InterpError::*; + use InterpErrorKind::*; use UndefinedBehaviorInfo::*; let mut msg = vec![]; diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index de293495e8618..59776a484b579 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -245,17 +245,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let val = match which { Op::MirOp(mir_op) => { // This does NaN adjustments. - let val = this.binary_op(mir_op, &left, &right).map_err(|err| { - match err.kind() { - &InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ShiftOverflow { shift_amount, .. }) => { + let val = this.binary_op(mir_op, &left, &right).map_err_kind(|kind| { + match kind { + InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ShiftOverflow { shift_amount, .. }) => { // This resets the interpreter backtrace, but it's not worth avoiding that. let shift_amount = match shift_amount { Either::Left(v) => v.to_string(), Either::Right(v) => v.to_string(), }; - err_ub_format!("overflowing shift by {shift_amount} in `simd_{intrinsic_name}` in lane {i}").into() + err_ub_format!("overflowing shift by {shift_amount} in `simd_{intrinsic_name}` in lane {i}") } - _ => err + kind => kind } })?; if matches!(mir_op, BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge) { diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 7fce5b6330696..f6f91e589697a 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -289,11 +289,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_get_alloc_id" => { let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; - let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err(|_e| { + let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err_kind(|_e| { err_machine_stop!(TerminationInfo::Abort(format!( "pointer passed to `miri_get_alloc_id` must not be dangling, got {ptr:?}" ))) - .into() })?; this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?; }