/// up with a Rust-level backtrace of where the error occured.
/// Thsese should always be constructed by calling `.into()` on
/// a `InterpError`. In `librustc_mir::interpret`, we have the `err!`
-/// macro for this
+/// macro for this.
#[derive(Debug, Clone)]
pub struct InterpErrorInfo<'tcx> {
pub kind: InterpError<'tcx, u64>,
pub type AssertMessage<'tcx> = InterpError<'tcx, mir::Operand<'tcx>>;
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
+pub enum EvalErrorPanic<O> {
+ Panic {
+ msg: Symbol,
+ line: u32,
+ col: u32,
+ file: Symbol,
+ },
+ BoundsCheck {
+ len: O,
+ index: O,
+ },
+ Overflow(mir::BinOp),
+ OverflowNeg,
+ DivisionByZero,
+ RemainderByZero,
+}
+
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
pub enum InterpError<'tcx, O> {
/// This variant is used by machines to signal their own errors that do not
Unimplemented(String),
DerefFunctionPointer,
ExecuteMemory,
- BoundsCheck { len: O, index: O },
- Overflow(mir::BinOp),
- OverflowNeg,
- DivisionByZero,
- RemainderByZero,
Intrinsic(String),
InvalidChar(u128),
StackFrameLimitReached,
HeapAllocZeroBytes,
HeapAllocNonPowerOfTwoAlignment(u64),
Unreachable,
- Panic {
- msg: Symbol,
- line: u32,
- col: u32,
- file: Symbol,
- },
+ Panic(EvalErrorPanic<O>),
ReadFromReturnPointer,
PathNotFound(Vec<String>),
UnimplementedTraitSelection,
"tried to dereference a function pointer",
ExecuteMemory =>
"tried to treat a memory pointer as a function pointer",
- BoundsCheck{..} =>
- "array index out of bounds",
Intrinsic(..) =>
"intrinsic failed",
NoMirFor(..) =>
two",
Unreachable =>
"entered unreachable code",
- Panic { .. } =>
+ Panic(EvalErrorPanic::Panic{..}) =>
"the evaluated program panicked",
+ Panic(EvalErrorPanic::BoundsCheck{..}) =>
+ "array index out of bounds",
+ Panic(EvalErrorPanic::Overflow(mir::BinOp::Add)) =>
+ "attempt to add with overflow",
+ Panic(EvalErrorPanic::Overflow(mir::BinOp::Sub)) =>
+ "attempt to subtract with overflow",
+ Panic(EvalErrorPanic::Overflow(mir::BinOp::Mul)) =>
+ "attempt to multiply with overflow",
+ Panic(EvalErrorPanic::Overflow(mir::BinOp::Div)) =>
+ "attempt to divide with overflow",
+ Panic(EvalErrorPanic::Overflow(mir::BinOp::Rem)) =>
+ "attempt to calculate the remainder with overflow",
+ Panic(EvalErrorPanic::OverflowNeg) =>
+ "attempt to negate with overflow",
+ Panic(EvalErrorPanic::Overflow(mir::BinOp::Shr)) =>
+ "attempt to shift right with overflow",
+ Panic(EvalErrorPanic::Overflow(mir::BinOp::Shl)) =>
+ "attempt to shift left with overflow",
+ Panic(EvalErrorPanic::Overflow(op)) =>
+ bug!("{:?} cannot overflow", op),
+ Panic(EvalErrorPanic::DivisionByZero) =>
+ "attempt to divide by zero",
+ Panic(EvalErrorPanic::RemainderByZero) =>
+ "attempt to calculate the remainder with a divisor of zero",
ReadFromReturnPointer =>
"tried to read from the return pointer",
PathNotFound(_) =>
"encountered overly generic constant",
ReferencedConstant =>
"referenced constant has errors",
- Overflow(mir::BinOp::Add) => "attempt to add with overflow",
- Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",
- Overflow(mir::BinOp::Mul) => "attempt to multiply with overflow",
- Overflow(mir::BinOp::Div) => "attempt to divide with overflow",
- Overflow(mir::BinOp::Rem) => "attempt to calculate the remainder with overflow",
- OverflowNeg => "attempt to negate with overflow",
- Overflow(mir::BinOp::Shr) => "attempt to shift right with overflow",
- Overflow(mir::BinOp::Shl) => "attempt to shift left with overflow",
- Overflow(op) => bug!("{:?} cannot overflow", op),
- DivisionByZero => "attempt to divide by zero",
- RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
GeneratorResumedAfterReturn => "generator resumed after completion",
GeneratorResumedAfterPanic => "generator resumed after panicking",
InfiniteLoop =>
callee_ty, caller_ty),
FunctionArgCountMismatch =>
write!(f, "tried to call a function with incorrect number of arguments"),
- BoundsCheck { ref len, ref index } =>
- write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
ReallocatedWrongMemoryKind(ref old, ref new) =>
write!(f, "tried to reallocate memory from {} to {}", old, new),
DeallocatedWrongMemoryKind(ref old, ref new) =>
write!(f, "incorrect alloc info: expected size {} and align {}, \
got size {} and align {}",
size.bytes(), align.bytes(), size2.bytes(), align2.bytes()),
- Panic { ref msg, line, col, ref file } =>
+ Panic(EvalErrorPanic::Panic { ref msg, line, col, ref file }) =>
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col),
+ Panic(EvalErrorPanic::BoundsCheck { ref len, ref index }) =>
+ write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
InvalidDiscriminant(val) =>
write!(f, "encountered invalid enum discriminant {}", val),
Exit(code) =>