+ }
+ }
+}
+
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
+pub enum ResourceExhaustionInfo {
+ /// The stack grew too big.
+ StackFrameLimitReached,
+ /// The program ran into an infinite loop.
+ InfiniteLoop,
+}
+
+impl fmt::Debug for ResourceExhaustionInfo {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ use ResourceExhaustionInfo::*;
+ match self {
+ StackFrameLimitReached =>
+ write!(f, "reached the configured maximum number of stack frames"),
+ InfiniteLoop =>
+ write!(f, "duplicate interpreter state observed here, const evaluation will never \
+ terminate"),
+ }
+ }
+}
+
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
+pub enum InterpError<'tcx> {
+ /// The program panicked.
+ Panic(PanicInfo<u64>),
+ /// The program caused undefined behavior.
+ UndefinedBehaviour(UndefinedBehaviourInfo),
+ /// The program did something the interpreter does not support (some of these *might* be UB
+ /// but the interpreter is not sure).
+ Unsupported(UnsupportedOpInfo<'tcx>),
+ /// The program was invalid (ill-typed, not sufficiently monomorphized, ...).
+ InvalidProgram(InvalidProgramInfo<'tcx>),
+ /// The program exhausted the interpreter's resources (stack/heap too big,
+ /// execution takes too long, ..).
+ ResourceExhaustion(ResourceExhaustionInfo),
+ /// Not actually an interpreter error -- used to signal that execution has exited
+ /// with the given status code. Used by Miri, but not by CTFE.
+ Exit(i32),
+}
+
+pub type InterpResult<'tcx, T = ()> = Result<T, InterpErrorInfo<'tcx>>;
+
+impl fmt::Display for InterpError<'_> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // Forward `Display` to `Debug`
+ write!(f, "{:?}", self)
+ }
+}
+
+impl fmt::Debug for InterpError<'_> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ use InterpError::*;
+ match *self {
+ Unsupported(ref msg) =>
+ write!(f, "{:?}", msg),
+ InvalidProgram(ref msg) =>
+ write!(f, "{:?}", msg),
+ UndefinedBehaviour(ref msg) =>
+ write!(f, "{:?}", msg),
+ ResourceExhaustion(ref msg) =>
+ write!(f, "{:?}", msg),