diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index c8f42b1c604a5..6ab07c9679e7a 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -228,6 +228,24 @@ impl<'tcx> From> for InterpErrorInfo<'tcx> { pub type AssertMessage<'tcx> = InterpError<'tcx, mir::Operand<'tcx>>; +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum PanicMessage { + 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 @@ -266,11 +284,6 @@ pub enum InterpError<'tcx, O> { Unimplemented(String), DerefFunctionPointer, ExecuteMemory, - BoundsCheck { len: O, index: O }, - Overflow(mir::BinOp), - OverflowNeg, - DivisionByZero, - RemainderByZero, Intrinsic(String), InvalidChar(u128), StackFrameLimitReached, @@ -298,12 +311,7 @@ pub enum InterpError<'tcx, O> { HeapAllocZeroBytes, HeapAllocNonPowerOfTwoAlignment(u64), Unreachable, - Panic { - msg: Symbol, - line: u32, - col: u32, - file: Symbol, - }, + Panic(PanicMessage), ReadFromReturnPointer, PathNotFound(Vec), UnimplementedTraitSelection, @@ -369,8 +377,6 @@ impl<'tcx, O> InterpError<'tcx, O> { "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(..) => @@ -422,8 +428,32 @@ impl<'tcx, O> InterpError<'tcx, O> { two", Unreachable => "entered unreachable code", - Panic { .. } => + Panic(PanicMessage::Panic{..}) => "the evaluated program panicked", + Panic(PanicMessage::BoundsCheck{..}) => + "array index out of bounds", + Panic(PanicMessage::Overflow(mir::BinOp::Add)) => + "attempt to add with overflow", + Panic(PanicMessage::Overflow(mir::BinOp::Sub)) => + "attempt to subtract with overflow", + Panic(PanicMessage::Overflow(mir::BinOp::Mul)) => + "attempt to multiply with overflow", + Panic(PanicMessage::Overflow(mir::BinOp::Div)) => + "attempt to divide with overflow", + Panic(PanicMessage::Overflow(mir::BinOp::Rem)) => + "attempt to calculate the remainder with overflow", + Panic(PanicMessage::OverflowNeg) => + "attempt to negate with overflow", + Panic(PanicMessage::Overflow(mir::BinOp::Shr)) => + "attempt to shift right with overflow", + Panic(PanicMessage::Overflow(mir::BinOp::Shl)) => + "attempt to shift left with overflow", + Panic(PanicMessage::Overflow(op)) => + bug!("{:?} cannot overflow", op), + Panic(PanicMessage::DivisionByZero) => + "attempt to divide by zero", + Panic(PanicMessage::RemainderByZero) => + "attempt to calculate the remainder with a divisor of zero", ReadFromReturnPointer => "tried to read from the return pointer", PathNotFound(_) => @@ -436,17 +466,6 @@ impl<'tcx, O> InterpError<'tcx, O> { "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 => @@ -493,8 +512,6 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> { 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) => @@ -518,8 +535,10 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> { 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(PanicMessage::Panic { ref msg, line, col, ref file }) => write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col), + Panic(PanicMessage::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) => diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 1b294250aa3dc..5bec64d39fa62 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -12,7 +12,7 @@ mod pointer; pub use self::error::{ InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error, - FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, + FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicMessage }; pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue}; diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index a17bc1f67283d..0e3b8459115e3 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -5,7 +5,7 @@ use crate::ty::layout::{self, HasDataLayout, Size}; use rustc_macros::HashStable; use super::{ - AllocId, InterpResult, + AllocId, InterpResult, PanicMessage }; /// Used by `check_in_alloc` to indicate context of check @@ -76,13 +76,13 @@ pub trait PointerArithmetic: layout::HasDataLayout { #[inline] fn offset<'tcx>(&self, val: u64, i: u64) -> InterpResult<'tcx, u64> { let (res, over) = self.overflowing_offset(val, i); - if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) } + if over { err!(Panic(PanicMessage::Overflow(mir::BinOp::Add))) } else { Ok(res) } } #[inline] fn signed_offset<'tcx>(&self, val: u64, i: i64) -> InterpResult<'tcx, u64> { let (res, over) = self.overflowing_signed_offset(val, i128::from(i)); - if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) } + if over { err!(Panic(PanicMessage::Overflow(mir::BinOp::Add))) } else { Ok(res) } } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index d8b641fbe31f4..81f745de7bb41 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -7,7 +7,7 @@ use crate::hir::def::{CtorKind, Namespace}; use crate::hir::def_id::DefId; use crate::hir::{self, InlineAsm as HirInlineAsm}; -use crate::mir::interpret::{ConstValue, InterpError, Scalar}; +use crate::mir::interpret::{ConstValue, PanicMessage, InterpError::Panic, Scalar}; use crate::mir::visit::MirVisitable; use crate::rustc_serialize as serialize; use crate::ty::adjustment::PointerCast; @@ -3152,11 +3152,11 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { } } Assert { ref cond, expected, ref msg, target, cleanup } => { - let msg = if let InterpError::BoundsCheck { ref len, ref index } = *msg { - InterpError::BoundsCheck { + let msg = if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg { + Panic(PanicMessage::BoundsCheck { len: len.fold_with(folder), index: index.fold_with(folder), - } + }) } else { msg.clone() }; @@ -3197,7 +3197,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { } Assert { ref cond, ref msg, .. } => { if cond.visit_with(visitor) { - if let InterpError::BoundsCheck { ref len, ref index } = *msg { + if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg { len.visit_with(visitor) || index.visit_with(visitor) } else { false diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index c3a4566b5aee3..dca56cc526ce5 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -515,7 +515,8 @@ macro_rules! make_mir_visitor { msg: & $($mutability)? AssertMessage<'tcx>, location: Location) { use crate::mir::interpret::InterpError::*; - if let BoundsCheck { len, index } = msg { + use crate::mir::interpret::PanicMessage::BoundsCheck; + if let Panic(BoundsCheck { len, index }) = msg { self.visit_operand(len, location); self.visit_operand(index, location); } diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index d4b434ffe809c..b17902a5d615a 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -2,7 +2,7 @@ use rustc::middle::lang_items; use rustc::ty::{self, Ty, TypeFoldable, Instance}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt}; use rustc::mir::{self, Place, PlaceBase, Static, StaticKind}; -use rustc::mir::interpret::InterpError; +use rustc::mir::interpret::{InterpError, PanicMessage}; use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode}; use rustc_target::spec::abi::Abi; use crate::base; @@ -368,7 +368,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // checked operation, just a comparison with the minimum // value, so we have to check for the assert message. if !bx.check_overflow() { - if let mir::interpret::InterpError::OverflowNeg = *msg { + if let InterpError::Panic(PanicMessage::OverflowNeg) = *msg { const_cond = Some(expected); } } @@ -403,7 +403,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Put together the arguments to the panic entry point. let (lang_item, args) = match *msg { - InterpError::BoundsCheck { ref len, ref index } => { + InterpError::Panic(PanicMessage::BoundsCheck { ref len, ref index }) => { let len = self.codegen_operand(&mut bx, len).immediate(); let index = self.codegen_operand(&mut bx, index).immediate(); diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index cfc7e77f4e5a8..e4b561155b693 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -733,8 +733,8 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx cleanup: _, } => { self.consume_operand(loc, (cond, span), flow_state); - use rustc::mir::interpret::InterpError::BoundsCheck; - if let BoundsCheck { ref len, ref index } = *msg { + use rustc::mir::interpret::{InterpError::Panic, PanicMessage}; + if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg { self.consume_operand(loc, (len, span), flow_state); self.consume_operand(loc, (index, span), flow_state); } diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index c7b4a40305259..90df0c91c7235 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -207,8 +207,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { cleanup: _, } => { self.consume_operand(location, cond); - use rustc::mir::interpret::InterpError::BoundsCheck; - if let BoundsCheck { ref len, ref index } = *msg { + use rustc::mir::interpret::{InterpError::Panic, PanicMessage::BoundsCheck}; + if let Panic(BoundsCheck { ref len, ref index }) = *msg { self.consume_operand(location, len); self.consume_operand(location, index); } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index b0e364fa2dd9a..6ce2f968ed72d 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -28,7 +28,7 @@ use rustc::infer::canonical::QueryRegionConstraints; use rustc::infer::outlives::env::RegionBoundPairs; use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue}; +use rustc::mir::interpret::{InterpError::Panic, ConstValue, PanicMessage}; use rustc::mir::tcx::PlaceTy; use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext}; use rustc::mir::*; @@ -1606,7 +1606,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty); } - if let BoundsCheck { ref len, ref index } = *msg { + if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg { if len.ty(body, tcx) != tcx.types.usize { span_mirbug!(self, len, "bounds-check length non-usize {:?}", len) } diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 2d9e7ac75c7b8..42d08a728e0a7 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -4,7 +4,7 @@ use crate::build::expr::category::Category; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::hair::*; -use rustc::mir::interpret::InterpError::BoundsCheck; +use rustc::mir::interpret::{InterpError::Panic, PanicMessage::BoundsCheck}; use rustc::mir::*; use rustc::ty::{CanonicalUserTypeAnnotation, Variance}; @@ -105,10 +105,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ), ); - let msg = BoundsCheck { + let msg = Panic(BoundsCheck { len: Operand::Move(len), index: Operand::Copy(Place::from(idx)), - }; + }); let success = this.assert(block, Operand::Move(lt), true, msg, expr_span); success.and(slice.index(idx)) } diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 851a6b0b07cf6..8790ebc41693f 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -7,7 +7,7 @@ use crate::build::expr::category::{Category, RvalueFunc}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::hair::*; use rustc::middle::region; -use rustc::mir::interpret::InterpError; +use rustc::mir::interpret::{InterpError::Panic, PanicMessage}; use rustc::mir::*; use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts}; use syntax_pos::Span; @@ -101,7 +101,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, Operand::Move(is_min), false, - InterpError::OverflowNeg, + Panic(PanicMessage::OverflowNeg), expr_span, ); } @@ -401,7 +401,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let val = result_value.clone().field(val_fld, ty); let of = result_value.field(of_fld, bool_ty); - let err = InterpError::Overflow(op); + let err = Panic(PanicMessage::Overflow(op)); block = self.assert(block, Operand::Move(of), false, err, span); @@ -412,9 +412,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // and 2. there are two possible failure cases, divide-by-zero and overflow. let (zero_err, overflow_err) = if op == BinOp::Div { - (InterpError::DivisionByZero, InterpError::Overflow(op)) + (Panic(PanicMessage::DivisionByZero), Panic(PanicMessage::Overflow(op))) } else { - (InterpError::RemainderByZero, InterpError::Overflow(op)) + (Panic(PanicMessage::RemainderByZero), Panic(PanicMessage::Overflow(op))) }; // Check for / 0 diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index cf36c10a614e5..6623661f938fe 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -7,7 +7,7 @@ use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::mir::BinOp; use rustc::mir::interpret::{ - InterpResult, InterpError, Scalar, + InterpResult, InterpError, Scalar, PanicMessage, }; use super::{ @@ -261,7 +261,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let file = Symbol::intern(self.read_str(file_place)?); let line = self.read_scalar(line.into())?.to_u32()?; let col = self.read_scalar(col.into())?.to_u32()?; - return Err(InterpError::Panic { msg, file, line, col }.into()); + return Err(InterpError::Panic(PanicMessage::Panic { msg, file, line, col }).into()); } else if Some(def_id) == self.tcx.lang_items().begin_panic_fn() { assert!(args.len() == 2); // &'static str, &(&'static str, u32, u32) @@ -279,7 +279,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let file = Symbol::intern(self.read_str(file_place)?); let line = self.read_scalar(line.into())?.to_u32()?; let col = self.read_scalar(col.into())?.to_u32()?; - return Err(InterpError::Panic { msg, file, line, col }.into()); + return Err(InterpError::Panic(PanicMessage::Panic { msg, file, line, col }).into()); } else { return Ok(false); } diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index 20180c9cba542..b4edee72a4d19 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -2,7 +2,7 @@ use rustc::mir; use rustc::ty::{self, layout::TyLayout}; use syntax::ast::FloatTy; use rustc_apfloat::Float; -use rustc::mir::interpret::{InterpResult, Scalar}; +use rustc::mir::interpret::{InterpResult, PanicMessage, Scalar}; use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy}; @@ -173,8 +173,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok((Scalar::from_bool(op(&l, &r)), false)); } let op: Option (i128, bool)> = match bin_op { - Div if r == 0 => return err!(DivisionByZero), - Rem if r == 0 => return err!(RemainderByZero), + Div if r == 0 => return err!(Panic(PanicMessage::DivisionByZero)), + Rem if r == 0 => return err!(Panic(PanicMessage::RemainderByZero)), Div => Some(i128::overflowing_div), Rem => Some(i128::overflowing_rem), Add => Some(i128::overflowing_add), @@ -231,8 +231,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Add => u128::overflowing_add, Sub => u128::overflowing_sub, Mul => u128::overflowing_mul, - Div if r == 0 => return err!(DivisionByZero), - Rem if r == 0 => return err!(RemainderByZero), + Div if r == 0 => return err!(Panic(PanicMessage::DivisionByZero)), + Rem if r == 0 => return err!(Panic(PanicMessage::RemainderByZero)), Div => u128::overflowing_div, Rem => u128::overflowing_rem, _ => bug!(), diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 68382071b4a67..8fe882934dfb5 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -13,7 +13,7 @@ use rustc::ty::TypeFoldable; use super::{ GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic, - InterpCx, Machine, AllocMap, AllocationExtra, + InterpCx, Machine, AllocMap, AllocationExtra, PanicMessage, RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue }; @@ -356,7 +356,7 @@ where // This can be violated because this runs during promotion on code where the // type system has not yet ensured that such things don't happen. debug!("tried to access element {} of array/slice with length {}", field, len); - return err!(BoundsCheck { len, index: field }); + return err!(Panic(PanicMessage::BoundsCheck { len, index: field })); } stride * field } diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 75690b4d361c6..a85b77c7b8143 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -7,7 +7,7 @@ use syntax::source_map::Span; use rustc_target::spec::abi::Abi; use super::{ - InterpResult, PointerArithmetic, InterpError, Scalar, + InterpResult, PointerArithmetic, InterpError, Scalar, PanicMessage, InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal, }; @@ -137,19 +137,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Compute error message use rustc::mir::interpret::InterpError::*; return match *msg { - BoundsCheck { ref len, ref index } => { + Panic(PanicMessage::BoundsCheck { ref len, ref index }) => { let len = self.read_immediate(self.eval_operand(len, None)?) .expect("can't eval len").to_scalar()? .to_bits(self.memory().pointer_size())? as u64; let index = self.read_immediate(self.eval_operand(index, None)?) .expect("can't eval index").to_scalar()? .to_bits(self.memory().pointer_size())? as u64; - err!(BoundsCheck { len, index }) + err!(Panic(PanicMessage::BoundsCheck { len, index })) } - Overflow(op) => Err(Overflow(op).into()), - OverflowNeg => Err(OverflowNeg.into()), - DivisionByZero => Err(DivisionByZero.into()), - RemainderByZero => Err(RemainderByZero.into()), + Panic(PanicMessage::Overflow(op)) => + Err(Panic(PanicMessage::Overflow(op)).into()), + Panic(PanicMessage::OverflowNeg) => + Err(Panic(PanicMessage::OverflowNeg).into()), + Panic(PanicMessage::DivisionByZero) => + Err(Panic(PanicMessage::DivisionByZero).into()), + Panic(PanicMessage::RemainderByZero) => + Err(Panic(PanicMessage::RemainderByZero).into()), GeneratorResumedAfterReturn | GeneratorResumedAfterPanic => unimplemented!(), _ => bug!(), diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 72390228aa839..37fcd744a3883 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -13,7 +13,7 @@ use rustc::mir::{ use rustc::mir::visit::{ Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext, }; -use rustc::mir::interpret::{InterpError, Scalar, GlobalId, InterpResult}; +use rustc::mir::interpret::{InterpError::Panic, Scalar, GlobalId, InterpResult, PanicMessage}; use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; use syntax_pos::{Span, DUMMY_SP}; use rustc::ty::subst::InternalSubsts; @@ -339,12 +339,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // FIXME: implement => {}, - | Panic { .. } - | BoundsCheck{..} - | Overflow(_) - | OverflowNeg - | DivisionByZero - | RemainderByZero + | Panic(_) => { diagnostic.report_as_lint( self.ecx.tcx, @@ -522,7 +517,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Need to do overflow check here: For actual CTFE, MIR // generation emits code that does this before calling the op. if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { - return err!(OverflowNeg); + return err!(Panic(PanicMessage::OverflowNeg)); } } UnOp::Not => { @@ -600,7 +595,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ) } else { if overflow { - let err = InterpError::Overflow(op).into(); + let err = Panic(PanicMessage::Overflow(op)).into(); let _: Option<()> = self.use_ecx(source_info, |_| Err(err)); return None; } @@ -838,11 +833,11 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { .expect("some part of a failing const eval must be local"); use rustc::mir::interpret::InterpError::*; let msg = match msg { - Overflow(_) | - OverflowNeg | - DivisionByZero | - RemainderByZero => msg.description().to_owned(), - BoundsCheck { ref len, ref index } => { + Panic(PanicMessage::Overflow(_)) | + Panic(PanicMessage::OverflowNeg) | + Panic(PanicMessage::DivisionByZero) | + Panic(PanicMessage::RemainderByZero) => msg.description().to_owned(), + Panic(PanicMessage::BoundsCheck { ref len, ref index }) => { let len = self .eval_operand(len, source_info) .expect("len must be const");