mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
interpret errors: add map_err_kind, rename InterpError -> InterpErrorKind
This commit is contained in:
parent
b27f33a4d9
commit
eea74be5c1
@ -11,7 +11,8 @@ use rustc_span::{Span, Symbol};
|
|||||||
use super::CompileTimeMachine;
|
use super::CompileTimeMachine;
|
||||||
use crate::errors::{self, FrameNote, ReportErrorExt};
|
use crate::errors::{self, FrameNote, ReportErrorExt};
|
||||||
use crate::interpret::{
|
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.
|
/// 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<InterpErrorInfo<'tcx>> for ConstEvalErrKind {
|
impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalErrKind {
|
||||||
fn into(self) -> InterpErrorInfo<'tcx> {
|
fn into(self) -> InterpErrorInfo<'tcx> {
|
||||||
err_machine_stop!(self).into()
|
err_machine_stop!(self).into()
|
||||||
@ -124,7 +125,7 @@ pub fn get_span_and_frames<'tcx>(
|
|||||||
/// `get_span_and_frames`.
|
/// `get_span_and_frames`.
|
||||||
pub(super) fn report<'tcx, C, F, E>(
|
pub(super) fn report<'tcx, C, F, E>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
error: InterpError<'tcx>,
|
error: InterpErrorKind<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
get_span_and_frames: C,
|
get_span_and_frames: C,
|
||||||
mk: F,
|
mk: F,
|
||||||
|
@ -18,7 +18,7 @@ use tracing::{debug, instrument, trace};
|
|||||||
use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
|
use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
|
||||||
use crate::const_eval::CheckAlignment;
|
use crate::const_eval::CheckAlignment;
|
||||||
use crate::interpret::{
|
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,
|
InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup, create_static_alloc,
|
||||||
eval_nullary_intrinsic, intern_const_alloc_recursive, interp_ok, throw_exhaust,
|
eval_nullary_intrinsic, intern_const_alloc_recursive, interp_ok, throw_exhaust,
|
||||||
};
|
};
|
||||||
@ -463,7 +463,7 @@ fn report_validation_error<'tcx>(
|
|||||||
error: InterpErrorInfo<'tcx>,
|
error: InterpErrorInfo<'tcx>,
|
||||||
alloc_id: AllocId,
|
alloc_id: AllocId,
|
||||||
) -> ErrorHandled {
|
) -> ErrorHandled {
|
||||||
if !matches!(error.kind(), InterpError::UndefinedBehavior(_)) {
|
if !matches!(error.kind(), InterpErrorKind::UndefinedBehavior(_)) {
|
||||||
// Some other error happened during validation, e.g. an unsupported operation.
|
// Some other error happened during validation, e.g. an unsupported operation.
|
||||||
return report_eval_error(ecx, cid, error);
|
return report_eval_error(ecx, cid, error);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use rustc_errors::{
|
|||||||
use rustc_hir::ConstContext;
|
use rustc_hir::ConstContext;
|
||||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||||
use rustc_middle::mir::interpret::{
|
use rustc_middle::mir::interpret::{
|
||||||
CheckInAllocMsg, CtfeProvenance, ExpectedKind, InterpError, InvalidMetaKind,
|
CheckInAllocMsg, CtfeProvenance, ExpectedKind, InterpErrorKind, InvalidMetaKind,
|
||||||
InvalidProgramInfo, Misalignment, Pointer, PointerKind, ResourceExhaustionInfo,
|
InvalidProgramInfo, Misalignment, Pointer, PointerKind, ResourceExhaustionInfo,
|
||||||
UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo,
|
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 {
|
fn diagnostic_message(&self) -> DiagMessage {
|
||||||
match self {
|
match self {
|
||||||
InterpError::UndefinedBehavior(ub) => ub.diagnostic_message(),
|
InterpErrorKind::UndefinedBehavior(ub) => ub.diagnostic_message(),
|
||||||
InterpError::Unsupported(e) => e.diagnostic_message(),
|
InterpErrorKind::Unsupported(e) => e.diagnostic_message(),
|
||||||
InterpError::InvalidProgram(e) => e.diagnostic_message(),
|
InterpErrorKind::InvalidProgram(e) => e.diagnostic_message(),
|
||||||
InterpError::ResourceExhaustion(e) => e.diagnostic_message(),
|
InterpErrorKind::ResourceExhaustion(e) => e.diagnostic_message(),
|
||||||
InterpError::MachineStop(e) => e.diagnostic_message(),
|
InterpErrorKind::MachineStop(e) => e.diagnostic_message(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
match self {
|
match self {
|
||||||
InterpError::UndefinedBehavior(ub) => ub.add_args(diag),
|
InterpErrorKind::UndefinedBehavior(ub) => ub.add_args(diag),
|
||||||
InterpError::Unsupported(e) => e.add_args(diag),
|
InterpErrorKind::Unsupported(e) => e.add_args(diag),
|
||||||
InterpError::InvalidProgram(e) => e.add_args(diag),
|
InterpErrorKind::InvalidProgram(e) => e.add_args(diag),
|
||||||
InterpError::ResourceExhaustion(e) => e.add_args(diag),
|
InterpErrorKind::ResourceExhaustion(e) => e.add_args(diag),
|
||||||
InterpError::MachineStop(e) => e.add_args(&mut |name, value| {
|
InterpErrorKind::MachineStop(e) => e.add_args(&mut |name, value| {
|
||||||
diag.arg(name, value);
|
diag.arg(name, value);
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
@ -471,7 +471,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||||||
// Don't forget to mark "initially live" locals as live.
|
// Don't forget to mark "initially live" locals as live.
|
||||||
self.storage_live_for_always_live_locals()?;
|
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.
|
// Don't show the incomplete stack frame in the error stacktrace.
|
||||||
self.stack_mut().pop();
|
self.stack_mut().pop();
|
||||||
})
|
})
|
||||||
|
@ -19,7 +19,7 @@ use rustc_trait_selection::traits::ObligationCtxt;
|
|||||||
use tracing::{debug, instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
|
|
||||||
use super::{
|
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,
|
MemPlaceMeta, Memory, OpTy, Place, PlaceTy, PointerArithmetic, Projectable, Provenance,
|
||||||
err_inval, interp_ok, throw_inval, throw_ub, throw_ub_custom,
|
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> {
|
impl<'tcx, M: Machine<'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'tcx, M> {
|
||||||
type LayoutOfResult = Result<TyAndLayout<'tcx>, InterpError<'tcx>>;
|
type LayoutOfResult = Result<TyAndLayout<'tcx>, InterpErrorKind<'tcx>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn layout_tcx_at_span(&self) -> Span {
|
fn layout_tcx_at_span(&self) -> Span {
|
||||||
@ -82,20 +82,25 @@ impl<'tcx, M: Machine<'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'tcx, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[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))
|
err_inval!(Layout(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> {
|
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(
|
fn handle_fn_abi_err(
|
||||||
&self,
|
&self,
|
||||||
err: FnAbiError<'tcx>,
|
err: FnAbiError<'tcx>,
|
||||||
_span: Span,
|
_span: Span,
|
||||||
_fn_abi_request: FnAbiRequest<'tcx>,
|
_fn_abi_request: FnAbiRequest<'tcx>,
|
||||||
) -> InterpError<'tcx> {
|
) -> InterpErrorKind<'tcx> {
|
||||||
match err {
|
match err {
|
||||||
FnAbiError::Layout(err) => err_inval!(Layout(err)),
|
FnAbiError::Layout(err) => err_inval!(Layout(err)),
|
||||||
FnAbiError::AdjustForForeignAbi(err) => {
|
FnAbiError::AdjustForForeignAbi(err) => {
|
||||||
|
@ -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
|
dist.checked_neg().unwrap(), // i64::MIN is impossible as no allocation can be that large
|
||||||
CheckInAllocMsg::OffsetFromTest,
|
CheckInAllocMsg::OffsetFromTest,
|
||||||
)
|
)
|
||||||
.map_err(|_| {
|
.map_err_kind(|_| {
|
||||||
// Make the error more specific.
|
// Make the error more specific.
|
||||||
err_ub_custom!(
|
err_ub_custom!(
|
||||||
fluent::const_eval_offset_from_different_allocations,
|
fluent::const_eval_offset_from_different_allocations,
|
||||||
name = intrinsic_name,
|
name = intrinsic_name,
|
||||||
)
|
)
|
||||||
.into()
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Perform division by size to compute return value.
|
// Perform division by size to compute return value.
|
||||||
|
@ -17,8 +17,8 @@ use rustc_hir as hir;
|
|||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::mir::interpret::ValidationErrorKind::{self, *};
|
use rustc_middle::mir::interpret::ValidationErrorKind::{self, *};
|
||||||
use rustc_middle::mir::interpret::{
|
use rustc_middle::mir::interpret::{
|
||||||
ExpectedKind, InterpError, InterpErrorInfo, InvalidMetaKind, Misalignment, PointerKind,
|
ExpectedKind, InterpErrorKind, InvalidMetaKind, Misalignment, PointerKind, Provenance,
|
||||||
Provenance, UnsupportedOpInfo, ValidationErrorInfo, alloc_range, interp_ok,
|
UnsupportedOpInfo, ValidationErrorInfo, alloc_range, interp_ok,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
|
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
@ -37,8 +37,8 @@ use super::{
|
|||||||
|
|
||||||
// for the validation errors
|
// for the validation errors
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
use super::InterpError::UndefinedBehavior as Ub;
|
use super::InterpErrorKind::UndefinedBehavior as Ub;
|
||||||
use super::InterpError::Unsupported as Unsup;
|
use super::InterpErrorKind::Unsupported as Unsup;
|
||||||
use super::UndefinedBehaviorInfo::*;
|
use super::UndefinedBehaviorInfo::*;
|
||||||
use super::UnsupportedOpInfo::*;
|
use super::UnsupportedOpInfo::*;
|
||||||
|
|
||||||
@ -97,20 +97,19 @@ macro_rules! try_validation {
|
|||||||
($e:expr, $where:expr,
|
($e:expr, $where:expr,
|
||||||
$( $( $p:pat_param )|+ => $kind: 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
|
// 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.
|
// allocation here as this can only slow down builds that fail anyway.
|
||||||
let (kind, backtrace) = e.into_parts();
|
match e {
|
||||||
match kind {
|
|
||||||
$(
|
$(
|
||||||
$($p)|+ => {
|
$($p)|+ => {
|
||||||
err_validation_failure!(
|
err_validation_failure!(
|
||||||
$where,
|
$where,
|
||||||
$kind
|
$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.
|
// 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");
|
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.
|
// Some error happened, try to provide a more detailed description.
|
||||||
// For some errors we might be able to provide extra information.
|
// For some errors we might be able to provide extra information.
|
||||||
// (This custom logic does not fit the `try_validation!` macro.)
|
// (This custom logic does not fit the `try_validation!` macro.)
|
||||||
let (kind, backtrace) = err.into_parts();
|
|
||||||
match kind {
|
match kind {
|
||||||
Ub(InvalidUninitBytes(Some((_alloc_id, access)))) | Unsup(ReadPointerAsInt(Some((_alloc_id, access)))) => {
|
Ub(InvalidUninitBytes(Some((_alloc_id, access)))) | Unsup(ReadPointerAsInt(Some((_alloc_id, access)))) => {
|
||||||
// Some byte was uninitialized, determine which
|
// 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));
|
self.path.push(PathElem::ArrayElem(i));
|
||||||
|
|
||||||
if matches!(kind, Ub(InvalidUninitBytes(_))) {
|
if matches!(kind, Ub(InvalidUninitBytes(_))) {
|
||||||
err_validation_failure!(self.path, Uninit { expected }).into()
|
err_validation_failure!(self.path, Uninit { expected })
|
||||||
} else {
|
} 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).
|
// 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)?;
|
v.reset_padding(val)?;
|
||||||
interp_ok(())
|
interp_ok(())
|
||||||
})
|
})
|
||||||
.map_err(|err| {
|
.map_err_info(|err| {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
err.kind(),
|
err.kind(),
|
||||||
err_ub!(ValidationError { .. })
|
err_ub!(ValidationError { .. })
|
||||||
| InterpError::InvalidProgram(_)
|
| InterpErrorKind::InvalidProgram(_)
|
||||||
| InterpError::Unsupported(UnsupportedOpInfo::ExternTypeField)
|
| InterpErrorKind::Unsupported(UnsupportedOpInfo::ExternTypeField)
|
||||||
) {
|
) {
|
||||||
bug!(
|
bug!(
|
||||||
"Unexpected error during validation: {}",
|
"Unexpected error during validation: {}",
|
||||||
|
@ -18,9 +18,9 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable};
|
|||||||
use rustc_target::abi::{Align, HasDataLayout, Size};
|
use rustc_target::abi::{Align, HasDataLayout, Size};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
AllocId, BadBytesAccess, CtfeProvenance, InterpError, InterpResult, Pointer, PointerArithmetic,
|
AllocId, BadBytesAccess, CtfeProvenance, InterpErrorKind, InterpResult, Pointer,
|
||||||
Provenance, ResourceExhaustionInfo, Scalar, ScalarSizeMismatch, UndefinedBehaviorInfo,
|
PointerArithmetic, Provenance, ResourceExhaustionInfo, Scalar, ScalarSizeMismatch,
|
||||||
UnsupportedOpInfo, interp_ok, read_target_uint, write_target_uint,
|
UndefinedBehaviorInfo, UnsupportedOpInfo, interp_ok, read_target_uint, write_target_uint,
|
||||||
};
|
};
|
||||||
use crate::ty;
|
use crate::ty;
|
||||||
|
|
||||||
@ -199,22 +199,22 @@ impl From<ScalarSizeMismatch> for AllocError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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::*;
|
use AllocError::*;
|
||||||
match self {
|
match self {
|
||||||
ScalarSizeMismatch(s) => {
|
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))),
|
UnsupportedOpInfo::ReadPointerAsInt(info.map(|b| (alloc_id, b))),
|
||||||
),
|
),
|
||||||
OverwritePartialPointer(offset) => InterpError::Unsupported(
|
OverwritePartialPointer(offset) => InterpErrorKind::Unsupported(
|
||||||
UnsupportedOpInfo::OverwritePartialPointer(Pointer::new(alloc_id, offset)),
|
UnsupportedOpInfo::OverwritePartialPointer(Pointer::new(alloc_id, offset)),
|
||||||
),
|
),
|
||||||
ReadPartialPointer(offset) => InterpError::Unsupported(
|
ReadPartialPointer(offset) => InterpErrorKind::Unsupported(
|
||||||
UnsupportedOpInfo::ReadPartialPointer(Pointer::new(alloc_id, offset)),
|
UnsupportedOpInfo::ReadPartialPointer(Pointer::new(alloc_id, offset)),
|
||||||
),
|
),
|
||||||
InvalidUninitBytes(info) => InterpError::UndefinedBehavior(
|
InvalidUninitBytes(info) => InterpErrorKind::UndefinedBehavior(
|
||||||
UndefinedBehaviorInfo::InvalidUninitBytes(info.map(|b| (alloc_id, b))),
|
UndefinedBehaviorInfo::InvalidUninitBytes(info.map(|b| (alloc_id, b))),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -318,7 +318,7 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
|
|||||||
pub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self> {
|
pub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self> {
|
||||||
Self::uninit_inner(size, align, || {
|
Self::uninit_inner(size, align, || {
|
||||||
ty::tls::with(|tcx| tcx.dcx().delayed_bug("exhausted memory during interpretation"));
|
ty::tls::with(|tcx| tcx.dcx().delayed_bug("exhausted memory during interpretation"));
|
||||||
InterpError::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted)
|
InterpErrorKind::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted)
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ pub struct InterpErrorInfo<'tcx>(Box<InterpErrorInfoInner<'tcx>>);
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct InterpErrorInfoInner<'tcx> {
|
struct InterpErrorInfoInner<'tcx> {
|
||||||
kind: InterpError<'tcx>,
|
kind: InterpErrorKind<'tcx>,
|
||||||
backtrace: InterpErrorBacktrace,
|
backtrace: InterpErrorBacktrace,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,21 +154,21 @@ impl InterpErrorBacktrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> InterpErrorInfo<'tcx> {
|
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;
|
let InterpErrorInfo(box InterpErrorInfoInner { kind, backtrace }) = self;
|
||||||
(kind, backtrace)
|
(kind, backtrace)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_kind(self) -> InterpError<'tcx> {
|
pub fn into_kind(self) -> InterpErrorKind<'tcx> {
|
||||||
self.0.kind
|
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 }))
|
Self(Box::new(InterpErrorInfoInner { kind, backtrace }))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn kind(&self) -> &InterpError<'tcx> {
|
pub fn kind(&self) -> &InterpErrorKind<'tcx> {
|
||||||
&self.0.kind
|
&self.0.kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,13 +179,13 @@ fn print_backtrace(backtrace: &Backtrace) {
|
|||||||
|
|
||||||
impl From<ErrorGuaranteed> for InterpErrorInfo<'_> {
|
impl From<ErrorGuaranteed> for InterpErrorInfo<'_> {
|
||||||
fn from(err: ErrorGuaranteed) -> Self {
|
fn from(err: ErrorGuaranteed) -> Self {
|
||||||
InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err.into())).into()
|
InterpErrorKind::InvalidProgram(InvalidProgramInfo::AlreadyReported(err.into())).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ErrorHandled> for InterpErrorInfo<'_> {
|
impl From<ErrorHandled> for InterpErrorInfo<'_> {
|
||||||
fn from(err: ErrorHandled) -> Self {
|
fn from(err: ErrorHandled) -> Self {
|
||||||
InterpError::InvalidProgram(match err {
|
InterpErrorKind::InvalidProgram(match err {
|
||||||
ErrorHandled::Reported(r, _span) => InvalidProgramInfo::AlreadyReported(r),
|
ErrorHandled::Reported(r, _span) => InvalidProgramInfo::AlreadyReported(r),
|
||||||
ErrorHandled::TooGeneric(_span) => InvalidProgramInfo::TooGeneric,
|
ErrorHandled::TooGeneric(_span) => InvalidProgramInfo::TooGeneric,
|
||||||
})
|
})
|
||||||
@ -193,8 +193,8 @@ impl From<ErrorHandled> for InterpErrorInfo<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
|
impl<'tcx> From<InterpErrorKind<'tcx>> for InterpErrorInfo<'tcx> {
|
||||||
fn from(kind: InterpError<'tcx>) -> Self {
|
fn from(kind: InterpErrorKind<'tcx>) -> Self {
|
||||||
InterpErrorInfo(Box::new(InterpErrorInfoInner {
|
InterpErrorInfo(Box::new(InterpErrorInfoInner {
|
||||||
kind,
|
kind,
|
||||||
backtrace: InterpErrorBacktrace::new(),
|
backtrace: InterpErrorBacktrace::new(),
|
||||||
@ -590,7 +590,7 @@ impl dyn MachineStopType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum InterpError<'tcx> {
|
pub enum InterpErrorKind<'tcx> {
|
||||||
/// The program caused undefined behavior.
|
/// The program caused undefined behavior.
|
||||||
UndefinedBehavior(UndefinedBehaviorInfo<'tcx>),
|
UndefinedBehavior(UndefinedBehaviorInfo<'tcx>),
|
||||||
/// The program did something the interpreter does not support (some of these *might* be UB
|
/// 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<dyn MachineStopType>),
|
MachineStop(Box<dyn MachineStopType>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InterpError<'_> {
|
impl InterpErrorKind<'_> {
|
||||||
/// Some errors do string formatting even if the error is never printed.
|
/// 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,
|
/// 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.
|
/// so this method lets us detect them and `bug!` on unexpected errors.
|
||||||
pub fn formatted_string(&self) -> bool {
|
pub fn formatted_string(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self,
|
self,
|
||||||
InterpError::Unsupported(UnsupportedOpInfo::Unsupported(_))
|
InterpErrorKind::Unsupported(UnsupportedOpInfo::Unsupported(_))
|
||||||
| InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ValidationError { .. })
|
| InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ValidationError { .. })
|
||||||
| InterpError::UndefinedBehavior(UndefinedBehaviorInfo::Ub(_))
|
| InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::Ub(_))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Macros for constructing / throwing `InterpError`
|
// Macros for constructing / throwing `InterpErrorKind`
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! err_unsup {
|
macro_rules! err_unsup {
|
||||||
($($tt:tt)*) => {
|
($($tt:tt)*) => {
|
||||||
$crate::mir::interpret::InterpError::Unsupported(
|
$crate::mir::interpret::InterpErrorKind::Unsupported(
|
||||||
$crate::mir::interpret::UnsupportedOpInfo::$($tt)*
|
$crate::mir::interpret::UnsupportedOpInfo::$($tt)*
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@ -638,7 +638,7 @@ macro_rules! err_unsup_format {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! err_inval {
|
macro_rules! err_inval {
|
||||||
($($tt:tt)*) => {
|
($($tt:tt)*) => {
|
||||||
$crate::mir::interpret::InterpError::InvalidProgram(
|
$crate::mir::interpret::InterpErrorKind::InvalidProgram(
|
||||||
$crate::mir::interpret::InvalidProgramInfo::$($tt)*
|
$crate::mir::interpret::InvalidProgramInfo::$($tt)*
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@ -647,7 +647,7 @@ macro_rules! err_inval {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! err_ub {
|
macro_rules! err_ub {
|
||||||
($($tt:tt)*) => {
|
($($tt:tt)*) => {
|
||||||
$crate::mir::interpret::InterpError::UndefinedBehavior(
|
$crate::mir::interpret::InterpErrorKind::UndefinedBehavior(
|
||||||
$crate::mir::interpret::UndefinedBehaviorInfo::$($tt)*
|
$crate::mir::interpret::UndefinedBehaviorInfo::$($tt)*
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@ -680,7 +680,7 @@ macro_rules! err_ub_custom {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! err_exhaust {
|
macro_rules! err_exhaust {
|
||||||
($($tt:tt)*) => {
|
($($tt:tt)*) => {
|
||||||
$crate::mir::interpret::InterpError::ResourceExhaustion(
|
$crate::mir::interpret::InterpErrorKind::ResourceExhaustion(
|
||||||
$crate::mir::interpret::ResourceExhaustionInfo::$($tt)*
|
$crate::mir::interpret::ResourceExhaustionInfo::$($tt)*
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@ -689,7 +689,7 @@ macro_rules! err_exhaust {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! err_machine_stop {
|
macro_rules! err_machine_stop {
|
||||||
($($tt:tt)*) => {
|
($($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_`.
|
// Allow `yeet`ing `InterpError` in functions returning `InterpResult_`.
|
||||||
impl<'tcx, T> ops::FromResidual<ops::Yeet<InterpError<'tcx>>> for InterpResult_<'tcx, T> {
|
impl<'tcx, T> ops::FromResidual<ops::Yeet<InterpErrorKind<'tcx>>> for InterpResult_<'tcx, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_residual(ops::Yeet(e): ops::Yeet<InterpError<'tcx>>) -> Self {
|
fn from_residual(ops::Yeet(e): ops::Yeet<InterpErrorKind<'tcx>>) -> Self {
|
||||||
Self::new(Err(e.into()))
|
Self::new(Err(e.into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -856,7 +856,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn map_err(
|
pub fn map_err_info(
|
||||||
self,
|
self,
|
||||||
f: impl FnOnce(InterpErrorInfo<'tcx>) -> InterpErrorInfo<'tcx>,
|
f: impl FnOnce(InterpErrorInfo<'tcx>) -> InterpErrorInfo<'tcx>,
|
||||||
) -> InterpResult<'tcx, T> {
|
) -> InterpResult<'tcx, T> {
|
||||||
@ -864,8 +864,19 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inspect_err(self, f: impl FnOnce(&InterpErrorInfo<'tcx>)) -> InterpResult<'tcx, T> {
|
pub fn map_err_kind(
|
||||||
InterpResult_::new(self.disarm().inspect_err(f))
|
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]
|
#[inline]
|
||||||
|
@ -36,7 +36,7 @@ pub use self::allocation::{
|
|||||||
pub use self::error::{
|
pub use self::error::{
|
||||||
BadBytesAccess, CheckAlignMsg, CheckInAllocMsg, ErrorHandled, EvalStaticInitializerRawResult,
|
BadBytesAccess, CheckAlignMsg, CheckInAllocMsg, ErrorHandled, EvalStaticInitializerRawResult,
|
||||||
EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, ExpectedKind,
|
EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, ExpectedKind,
|
||||||
InterpError, InterpErrorInfo, InterpResult, InvalidMetaKind, InvalidProgramInfo,
|
InterpErrorInfo, InterpErrorKind, InterpResult, InvalidMetaKind, InvalidProgramInfo,
|
||||||
MachineStopType, Misalignment, PointerKind, ReportedErrorInfo, ResourceExhaustionInfo,
|
MachineStopType, Misalignment, PointerKind, ReportedErrorInfo, ResourceExhaustionInfo,
|
||||||
ScalarSizeMismatch, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo,
|
ScalarSizeMismatch, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo,
|
||||||
ValidationErrorKind, interp_ok,
|
ValidationErrorKind, interp_ok,
|
||||||
|
@ -232,7 +232,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||||||
F: FnOnce(&mut Self) -> InterpResult<'tcx, T>,
|
F: FnOnce(&mut Self) -> InterpResult<'tcx, T>,
|
||||||
{
|
{
|
||||||
f(self)
|
f(self)
|
||||||
.map_err(|err| {
|
.map_err_info(|err| {
|
||||||
trace!("InterpCx operation failed: {:?}", err);
|
trace!("InterpCx operation failed: {:?}", err);
|
||||||
// Some errors shouldn't come up because creating them causes
|
// Some errors shouldn't come up because creating them causes
|
||||||
// an allocation, which we should avoid. When that happens,
|
// an allocation, which we should avoid. When that happens,
|
||||||
|
@ -13,7 +13,7 @@ fn err_sb_ub<'tcx>(
|
|||||||
msg: String,
|
msg: String,
|
||||||
help: Vec<String>,
|
help: Vec<String>,
|
||||||
history: Option<TagHistory>,
|
history: Option<TagHistory>,
|
||||||
) -> InterpError<'tcx> {
|
) -> InterpErrorKind<'tcx> {
|
||||||
err_machine_stop!(TerminationInfo::StackedBorrowsUb { msg, help, history })
|
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`.
|
/// Report a descriptive error when `new` could not be granted from `derived_from`.
|
||||||
#[inline(never)] // This is only called on fatal code paths
|
#[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 {
|
let Operation::Retag(op) = &self.operation else {
|
||||||
unreachable!("grant_error should only be called during a retag")
|
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`.
|
/// Report a descriptive error when `access` is not permitted based on `tag`.
|
||||||
#[inline(never)] // This is only called on fatal code paths
|
#[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.
|
// Deallocation and retagging also do an access as part of their thing, so handle that here, too.
|
||||||
let op = match &self.operation {
|
let op = match &self.operation {
|
||||||
Operation::Access(op) => op,
|
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
|
#[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 {
|
let protected = match kind {
|
||||||
ProtectorKind::WeakProtector => "weakly protected",
|
ProtectorKind::WeakProtector => "weakly protected",
|
||||||
ProtectorKind::StrongProtector => "strongly 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
|
#[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 {
|
let Operation::Dealloc(op) = &self.operation else {
|
||||||
unreachable!("dealloc_error should only be called during a deallocation")
|
unreachable!("dealloc_error should only be called during a deallocation")
|
||||||
};
|
};
|
||||||
|
@ -298,7 +298,7 @@ pub(super) struct TbError<'node> {
|
|||||||
|
|
||||||
impl TbError<'_> {
|
impl TbError<'_> {
|
||||||
/// Produce a UB error.
|
/// Produce a UB error.
|
||||||
pub fn build<'tcx>(self) -> InterpError<'tcx> {
|
pub fn build<'tcx>(self) -> InterpErrorKind<'tcx> {
|
||||||
use TransitionError::*;
|
use TransitionError::*;
|
||||||
let cause = self.access_cause;
|
let cause = self.access_cause;
|
||||||
let accessed = self.accessed_info;
|
let accessed = self.accessed_info;
|
||||||
|
@ -674,7 +674,7 @@ impl<'tcx> Tree {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|args: ErrHandlerArgs<'_, TransitionError>| -> InterpError<'tcx> {
|
|args: ErrHandlerArgs<'_, TransitionError>| -> InterpErrorKind<'tcx> {
|
||||||
let ErrHandlerArgs { error_kind, conflicting_info, accessed_info } = args;
|
let ErrHandlerArgs { error_kind, conflicting_info, accessed_info } = args;
|
||||||
TbError {
|
TbError {
|
||||||
conflicting_info,
|
conflicting_info,
|
||||||
@ -772,7 +772,7 @@ impl<'tcx> Tree {
|
|||||||
let err_handler = |perms_range: Range<u64>,
|
let err_handler = |perms_range: Range<u64>,
|
||||||
access_cause: diagnostics::AccessCause,
|
access_cause: diagnostics::AccessCause,
|
||||||
args: ErrHandlerArgs<'_, TransitionError>|
|
args: ErrHandlerArgs<'_, TransitionError>|
|
||||||
-> InterpError<'tcx> {
|
-> InterpErrorKind<'tcx> {
|
||||||
let ErrHandlerArgs { error_kind, conflicting_info, accessed_info } = args;
|
let ErrHandlerArgs { error_kind, conflicting_info, accessed_info } = args;
|
||||||
TbError {
|
TbError {
|
||||||
conflicting_info,
|
conflicting_info,
|
||||||
|
@ -214,7 +214,7 @@ pub fn report_error<'tcx>(
|
|||||||
ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
|
ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
|
||||||
e: InterpErrorInfo<'tcx>,
|
e: InterpErrorInfo<'tcx>,
|
||||||
) -> Option<(i64, bool)> {
|
) -> Option<(i64, bool)> {
|
||||||
use InterpError::*;
|
use InterpErrorKind::*;
|
||||||
use UndefinedBehaviorInfo::*;
|
use UndefinedBehaviorInfo::*;
|
||||||
|
|
||||||
let mut msg = vec![];
|
let mut msg = vec![];
|
||||||
|
@ -245,17 +245,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||||||
let val = match which {
|
let val = match which {
|
||||||
Op::MirOp(mir_op) => {
|
Op::MirOp(mir_op) => {
|
||||||
// This does NaN adjustments.
|
// This does NaN adjustments.
|
||||||
let val = this.binary_op(mir_op, &left, &right).map_err(|err| {
|
let val = this.binary_op(mir_op, &left, &right).map_err_kind(|kind| {
|
||||||
match err.kind() {
|
match kind {
|
||||||
&InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ShiftOverflow { shift_amount, .. }) => {
|
InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ShiftOverflow { shift_amount, .. }) => {
|
||||||
// This resets the interpreter backtrace, but it's not worth avoiding that.
|
// This resets the interpreter backtrace, but it's not worth avoiding that.
|
||||||
let shift_amount = match shift_amount {
|
let shift_amount = match shift_amount {
|
||||||
Either::Left(v) => v.to_string(),
|
Either::Left(v) => v.to_string(),
|
||||||
Either::Right(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) {
|
if matches!(mir_op, BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge) {
|
||||||
|
@ -289,11 +289,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||||||
"miri_get_alloc_id" => {
|
"miri_get_alloc_id" => {
|
||||||
let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||||
let ptr = this.read_pointer(ptr)?;
|
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!(
|
err_machine_stop!(TerminationInfo::Abort(format!(
|
||||||
"pointer passed to `miri_get_alloc_id` must not be dangling, got {ptr:?}"
|
"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)?;
|
this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user