Merge ConstMathError into EvalErrorKind
This commit is contained in:
parent
671b2a5964
commit
cefcf0548e
12 changed files with 65 additions and 115 deletions
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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) =>
|
||||
|
|
|
|||
|
|
@ -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>)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue