|
2 | 2 | //! |
3 | 3 | //! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html |
4 | 4 |
|
5 | | -use crate::mir::interpret::{GlobalAlloc, PanicInfo, Scalar}; |
| 5 | +use crate::mir::interpret::{GlobalAlloc, Scalar}; |
6 | 6 | use crate::mir::visit::MirVisitable; |
7 | 7 | use crate::ty::adjustment::PointerCast; |
8 | 8 | use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; |
@@ -36,7 +36,6 @@ pub use syntax::ast::Mutability; |
36 | 36 | use syntax::ast::Name; |
37 | 37 |
|
38 | 38 | pub use self::cache::{BodyAndCache, ReadOnlyBodyAndCache}; |
39 | | -pub use self::interpret::AssertMessage; |
40 | 39 | pub use self::query::*; |
41 | 40 | pub use crate::read_only; |
42 | 41 |
|
@@ -1154,6 +1153,21 @@ pub enum TerminatorKind<'tcx> { |
1154 | 1153 | }, |
1155 | 1154 | } |
1156 | 1155 |
|
| 1156 | +/// Information about an assertion failure. |
| 1157 | +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, PartialEq)] |
| 1158 | +pub enum PanicInfo<O> { |
| 1159 | + BoundsCheck { len: O, index: O }, |
| 1160 | + Overflow(BinOp), |
| 1161 | + OverflowNeg, |
| 1162 | + DivisionByZero, |
| 1163 | + RemainderByZero, |
| 1164 | + ResumedAfterReturn(GeneratorKind), |
| 1165 | + ResumedAfterPanic(GeneratorKind), |
| 1166 | +} |
| 1167 | + |
| 1168 | +/// Type for MIR `Assert` terminator error messages. |
| 1169 | +pub type AssertMessage<'tcx> = PanicInfo<Operand<'tcx>>; |
| 1170 | + |
1157 | 1171 | pub type Successors<'a> = |
1158 | 1172 | iter::Chain<option::IntoIter<&'a BasicBlock>, slice::Iter<'a, BasicBlock>>; |
1159 | 1173 | pub type SuccessorsMut<'a> = |
@@ -1383,6 +1397,45 @@ impl<'tcx> BasicBlockData<'tcx> { |
1383 | 1397 | } |
1384 | 1398 | } |
1385 | 1399 |
|
| 1400 | +impl<O> PanicInfo<O> { |
| 1401 | + /// Getting a description does not require `O` to be printable, and does not |
| 1402 | + /// require allocation. |
| 1403 | + /// The caller is expected to handle `BoundsCheck` separately. |
| 1404 | + pub fn description(&self) -> &'static str { |
| 1405 | + use PanicInfo::*; |
| 1406 | + match self { |
| 1407 | + Overflow(BinOp::Add) => "attempt to add with overflow", |
| 1408 | + Overflow(BinOp::Sub) => "attempt to subtract with overflow", |
| 1409 | + Overflow(BinOp::Mul) => "attempt to multiply with overflow", |
| 1410 | + Overflow(BinOp::Div) => "attempt to divide with overflow", |
| 1411 | + Overflow(BinOp::Rem) => "attempt to calculate the remainder with overflow", |
| 1412 | + OverflowNeg => "attempt to negate with overflow", |
| 1413 | + Overflow(BinOp::Shr) => "attempt to shift right with overflow", |
| 1414 | + Overflow(BinOp::Shl) => "attempt to shift left with overflow", |
| 1415 | + Overflow(op) => bug!("{:?} cannot overflow", op), |
| 1416 | + DivisionByZero => "attempt to divide by zero", |
| 1417 | + RemainderByZero => "attempt to calculate the remainder with a divisor of zero", |
| 1418 | + ResumedAfterReturn(GeneratorKind::Gen) => "generator resumed after completion", |
| 1419 | + ResumedAfterReturn(GeneratorKind::Async(_)) => "`async fn` resumed after completion", |
| 1420 | + ResumedAfterPanic(GeneratorKind::Gen) => "generator resumed after panicking", |
| 1421 | + ResumedAfterPanic(GeneratorKind::Async(_)) => "`async fn` resumed after panicking", |
| 1422 | + BoundsCheck { .. } => bug!("Unexpected PanicInfo"), |
| 1423 | + } |
| 1424 | + } |
| 1425 | +} |
| 1426 | + |
| 1427 | +impl<O: fmt::Debug> fmt::Debug for PanicInfo<O> { |
| 1428 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 1429 | + use PanicInfo::*; |
| 1430 | + match self { |
| 1431 | + BoundsCheck { ref len, ref index } => { |
| 1432 | + write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index) |
| 1433 | + } |
| 1434 | + _ => write!(f, "{}", self.description()), |
| 1435 | + } |
| 1436 | + } |
| 1437 | +} |
| 1438 | + |
1386 | 1439 | impl<'tcx> Debug for TerminatorKind<'tcx> { |
1387 | 1440 | fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { |
1388 | 1441 | self.fmt_head(fmt)?; |
|
0 commit comments