+ GeneratorResumedAfterReturn,
+ GeneratorResumedAfterPanic,
+}
+
+/// Type for MIR `Assert` terminator error messages.
+pub type AssertMessage<'tcx> = PanicMessage<mir::Operand<'tcx>>;
+
+impl<O> PanicMessage<O> {
+ /// Getting a description does not require `O` to be printable, and does not
+ /// require allocation.
+ /// The caller is expected to handle `Panic` and `BoundsCheck` separately.
+ pub fn description(&self) -> &'static str {
+ use PanicMessage::*;
+ match self {
+ 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",
+ Panic { .. } | BoundsCheck { .. } =>
+ bug!("Unexpected PanicMessage"),
+ }
+ }
+}
+
+impl<O: fmt::Debug> fmt::Debug for PanicMessage<O> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ use PanicMessage::*;
+ match self {
+ Panic { ref msg, line, col, ref file } =>
+ write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col),
+ BoundsCheck { ref len, ref index } =>
+ write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
+ _ =>
+ write!(f, "{}", self.description()),
+ }
+ }