Merge ConstMathError into EvalErrorKind

This commit is contained in:
Oliver Schneider 2018-04-26 14:52:59 +02:00 committed by Oliver Schneider
parent 671b2a5964
commit cefcf0548e
No known key found for this signature in database
GPG key ID: 1D5CB4FC597C3004
12 changed files with 65 additions and 115 deletions

View file

@ -525,16 +525,26 @@ impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
predicates
});
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ::mir::interpret::EvalError<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.kind.hash_stable(hcx, hasher)
}
}
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ::mir::interpret::EvalErrorKind<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use mir::interpret::EvalErrorKind::*;
mem::discriminant(&self.kind).hash_stable(hcx, hasher);
mem::discriminant(&self).hash_stable(hcx, hasher);
match self.kind {
match *self {
DanglingPointerDeref |
DoubleFree |
InvalidMemoryAccess |
@ -565,8 +575,10 @@ for ::mir::interpret::EvalError<'gcx> {
TypeckError |
DerefFunctionPointer |
ExecuteMemory |
ReferencedConstant |
OverflowingMath => {}
OverflowNeg |
RemainderByZero |
DivisionByZero |
ReferencedConstant => {}
MachineError(ref err) => err.hash_stable(hcx, hasher),
FunctionPointerTyMismatch(a, b) => {
a.hash_stable(hcx, hasher);
@ -590,10 +602,6 @@ for ::mir::interpret::EvalError<'gcx> {
a.hash_stable(hcx, hasher);
b.hash_stable(hcx, hasher)
},
Math(sp, ref err) => {
sp.hash_stable(hcx, hasher);
err.hash_stable(hcx, hasher)
},
Intrinsic(ref s) => s.hash_stable(hcx, hasher),
InvalidChar(c) => c.hash_stable(hcx, hasher),
AbiViolation(ref s) => s.hash_stable(hcx, hasher),
@ -665,27 +673,11 @@ for ::mir::interpret::EvalError<'gcx> {
Layout(lay) => lay.hash_stable(hcx, hasher),
HeapAllocNonPowerOfTwoAlignment(n) => n.hash_stable(hcx, hasher),
PathNotFound(ref v) => v.hash_stable(hcx, hasher),
Overflow(op) => op.hash_stable(hcx, hasher),
}
}
}
impl_stable_hash_for!(enum mir::interpret::ConstMathErr {
Overflow(op),
DivisionByZero,
RemainderByZero,
});
impl_stable_hash_for!(enum mir::interpret::Op {
Add,
Sub,
Mul,
Div,
Rem,
Shr,
Shl,
Neg,
});
impl_stable_hash_for!(enum mir::interpret::Lock {
NoLock,
WriteLock(dl),

View file

@ -1,4 +1,3 @@
use std::error::Error;
use std::{fmt, env};
use mir;
@ -30,7 +29,7 @@ impl<'tcx> From<EvalErrorKind<'tcx>> for EvalError<'tcx> {
}
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
pub enum EvalErrorKind<'tcx> {
/// This variant is used by machines to signal their own errors that do not
/// match an existing variant
@ -60,9 +59,11 @@ pub enum EvalErrorKind<'tcx> {
DerefFunctionPointer,
ExecuteMemory,
ArrayIndexOutOfBounds(Span, u64, u64),
Math(Span, ConstMathErr),
Overflow(mir::BinOp),
OverflowNeg,
DivisionByZero,
RemainderByZero,
Intrinsic(String),
OverflowingMath,
InvalidChar(u128),
StackFrameLimitReached,
OutOfTls,
@ -124,10 +125,10 @@ pub enum EvalErrorKind<'tcx> {
pub type EvalResult<'tcx, T = ()> = Result<T, EvalError<'tcx>>;
impl<'tcx> Error for EvalError<'tcx> {
fn description(&self) -> &str {
impl<'tcx> EvalErrorKind<'tcx> {
pub fn description(&self) -> &str {
use self::EvalErrorKind::*;
match self.kind {
match *self {
MachineError(ref inner) => inner,
FunctionPointerTyMismatch(..) =>
"tried to call a function through a function pointer of a different type",
@ -176,12 +177,8 @@ impl<'tcx> Error for EvalError<'tcx> {
"tried to treat a memory pointer as a function pointer",
ArrayIndexOutOfBounds(..) =>
"array index out of bounds",
Math(..) =>
"mathematical operation failed",
Intrinsic(..) =>
"intrinsic failed",
OverflowingMath =>
"attempted to do overflowing math",
NoMirFor(..) =>
"mir not found",
InvalidChar(..) =>
@ -239,6 +236,17 @@ impl<'tcx> Error for EvalError<'tcx> {
"encountered constants with type errors, stopping evaluation",
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",
}
}
}
@ -280,8 +288,6 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
write!(f, "tried to reallocate memory from {} to {}", old, new),
DeallocatedWrongMemoryKind(ref old, ref new) =>
write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new),
Math(_, ref err) =>
write!(f, "{}", err.description()),
Intrinsic(ref err) =>
write!(f, "{}", err),
InvalidChar(c) =>
@ -299,45 +305,7 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
write!(f, "{}", inner),
IncorrectAllocationInformation(size, size2, align, align2) =>
write!(f, "incorrect alloc info: expected size {} and align {}, got size {} and align {}", size, align, size2, align2),
_ => write!(f, "{}", self.description()),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, RustcEncodable, RustcDecodable)]
pub enum ConstMathErr {
Overflow(Op),
DivisionByZero,
RemainderByZero,
}
pub use self::ConstMathErr::*;
#[derive(Debug, PartialEq, Eq, Clone, RustcEncodable, RustcDecodable)]
pub enum Op {
Add,
Sub,
Mul,
Div,
Rem,
Shr,
Shl,
Neg,
}
impl ConstMathErr {
pub fn description(&self) -> &'static str {
use self::Op::*;
match *self {
Overflow(Add) => "attempt to add with overflow",
Overflow(Sub) => "attempt to subtract with overflow",
Overflow(Mul) => "attempt to multiply with overflow",
Overflow(Div) => "attempt to divide with overflow",
Overflow(Rem) => "attempt to calculate the remainder with overflow",
Overflow(Neg) => "attempt to negate with overflow",
Overflow(Shr) => "attempt to shift right with overflow",
Overflow(Shl) => "attempt to shift left with overflow",
DivisionByZero => "attempt to divide by zero",
RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
_ => write!(f, "{}", self.kind.description()),
}
}
}

View file

@ -8,7 +8,7 @@ macro_rules! err {
mod error;
mod value;
pub use self::error::{EvalError, EvalResult, EvalErrorKind, Op, ConstMathErr};
pub use self::error::{EvalError, EvalResult, EvalErrorKind};
pub use self::value::{PrimVal, PrimValKind, Value, Pointer};
@ -23,7 +23,7 @@ use std::iter;
use syntax::ast::Mutability;
use rustc_serialize::{Encoder, Decoder, Decodable, Encodable};
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum Lock {
NoLock,
WriteLock(DynamicLifetime),
@ -31,13 +31,13 @@ pub enum Lock {
ReadLock(Vec<DynamicLifetime>),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct DynamicLifetime {
pub frame: usize,
pub region: Option<region::Scope>, // "None" indicates "until the function ends"
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum AccessKind {
Read,
Write,
@ -88,12 +88,12 @@ pub trait PointerArithmetic: layout::HasDataLayout {
fn signed_offset<'tcx>(self, val: u64, i: i64) -> EvalResult<'tcx, u64> {
let (res, over) = self.overflowing_signed_offset(val, i as i128);
if over { err!(OverflowingMath) } else { Ok(res) }
if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
}
fn offset<'tcx>(self, val: u64, i: u64) -> EvalResult<'tcx, u64> {
let (res, over) = self.overflowing_offset(val, i);
if over { err!(OverflowingMath) } else { Ok(res) }
if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
}
fn wrapping_signed_offset(self, val: u64, i: i64) -> u64 {

View file

@ -25,7 +25,7 @@ use rustc_serialize as serialize;
use hir::def::CtorKind;
use hir::def_id::DefId;
use mir::visit::MirVisitable;
use mir::interpret::{Value, PrimVal, ConstMathErr};
use mir::interpret::{Value, PrimVal, EvalErrorKind};
use ty::subst::{Subst, Substs};
use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, Region, Ty, TyCtxt, GeneratorInterior};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
@ -1211,7 +1211,7 @@ pub enum AssertMessage<'tcx> {
len: Operand<'tcx>,
index: Operand<'tcx>
},
Math(ConstMathErr),
Math(EvalErrorKind<'tcx>),
GeneratorResumedAfterReturn,
GeneratorResumedAfterPanic,
}
@ -1920,9 +1920,9 @@ pub fn print_miri_value<W: Write>(value: Value, ty: Ty, f: &mut W) -> fmt::Resul
(Value::ByVal(PrimVal::Bytes(0)), &TyBool) => write!(f, "false"),
(Value::ByVal(PrimVal::Bytes(1)), &TyBool) => write!(f, "true"),
(Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F32)) =>
write!(f, "{}", Single::from_bits(bits)),
write!(f, "{}f32", Single::from_bits(bits)),
(Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F64)) =>
write!(f, "{}", Double::from_bits(bits)),
write!(f, "{}f64", Double::from_bits(bits)),
(Value::ByVal(PrimVal::Bytes(n)), &TyUint(ui)) => write!(f, "{:?}{}", n, ui),
(Value::ByVal(PrimVal::Bytes(n)), &TyInt(i)) => write!(f, "{:?}{}", n as i128, i),
(Value::ByVal(PrimVal::Bytes(n)), &TyChar) =>

View file

@ -149,7 +149,7 @@ pub const FAT_PTR_ADDR: usize = 0;
/// - For a slice, this is the length.
pub const FAT_PTR_EXTRA: usize = 1;
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum LayoutError<'tcx> {
Unknown(Ty<'tcx>),
SizeOverflow(Ty<'tcx>)

View file

@ -505,9 +505,7 @@ impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
DerefFunctionPointer => DerefFunctionPointer,
ExecuteMemory => ExecuteMemory,
ArrayIndexOutOfBounds(sp, a, b) => ArrayIndexOutOfBounds(sp, a, b),
Math(sp, ref err) => Math(sp, err.clone()),
Intrinsic(ref s) => Intrinsic(s.clone()),
OverflowingMath => OverflowingMath,
InvalidChar(c) => InvalidChar(c),
StackFrameLimitReached => StackFrameLimitReached,
OutOfTls => OutOfTls,
@ -568,6 +566,10 @@ impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
UnimplementedTraitSelection => UnimplementedTraitSelection,
TypeckError => TypeckError,
ReferencedConstant => ReferencedConstant,
OverflowNeg => OverflowNeg,
Overflow(op) => Overflow(op),
DivisionByZero => DivisionByZero,
RemainderByZero => RemainderByZero,
};
Some(interpret::EvalError {
kind: kind,