Skip to content

Commit

Permalink
Merge ConstMathError into EvalErrorKind
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Apr 30, 2018
1 parent 671b2a5 commit cefcf05
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 115 deletions.
42 changes: 17 additions & 25 deletions src/librustc/ich/impls_ty.rs
Expand Up @@ -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 |
Expand Down Expand Up @@ -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);
Expand All @@ -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),
Expand Down Expand Up @@ -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),
Expand Down
72 changes: 20 additions & 52 deletions src/librustc/mir/interpret/error.rs
@@ -1,4 +1,3 @@
use std::error::Error;
use std::{fmt, env};

use mir;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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(..) =>
Expand Down Expand Up @@ -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",
}
}
}
Expand Down Expand Up @@ -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) =>
Expand All @@ -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()),
}
}
}
12 changes: 6 additions & 6 deletions src/librustc/mir/interpret/mod.rs
Expand Up @@ -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};

Expand All @@ -23,21 +23,21 @@ 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),
/// This should never be empty -- that would be a read lock held and nobody there to release it...
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,
Expand Down Expand Up @@ -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 {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/mir/mod.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -1211,7 +1211,7 @@ pub enum AssertMessage<'tcx> {
len: Operand<'tcx>,
index: Operand<'tcx>
},
Math(ConstMathErr),
Math(EvalErrorKind<'tcx>),
GeneratorResumedAfterReturn,
GeneratorResumedAfterPanic,
}
Expand Down Expand Up @@ -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) =>
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/layout.rs
Expand Up @@ -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>)
Expand Down
6 changes: 4 additions & 2 deletions src/librustc/ty/structural_impls.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
23 changes: 7 additions & 16 deletions src/librustc_mir/build/expr/as_rvalue.rs
Expand Up @@ -20,7 +20,7 @@ use rustc::middle::const_val::ConstVal;
use rustc::middle::region;
use rustc::ty::{self, Ty};
use rustc::mir::*;
use rustc::mir::interpret::{Value, PrimVal, ConstMathErr, Op};
use rustc::mir::interpret::{Value, PrimVal, EvalErrorKind};
use syntax_pos::Span;

impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
Expand Down Expand Up @@ -85,7 +85,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
this.cfg.push_assign(block, source_info, &is_min,
Rvalue::BinaryOp(BinOp::Eq, arg.to_copy(), minval));

let err = ConstMathErr::Overflow(Op::Neg);
let err = EvalErrorKind::OverflowNeg;
block = this.assert(block, Operand::Move(is_min), false,
AssertMessage::Math(err), expr_span);
}
Expand Down Expand Up @@ -310,16 +310,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let val = result_value.clone().field(val_fld, ty);
let of = result_value.field(of_fld, bool_ty);

let err = ConstMathErr::Overflow(match op {
BinOp::Add => Op::Add,
BinOp::Sub => Op::Sub,
BinOp::Mul => Op::Mul,
BinOp::Shl => Op::Shl,
BinOp::Shr => Op::Shr,
_ => {
bug!("MIR build_binary_op: {:?} is not checkable", op)
}
});
let err = EvalErrorKind::Overflow(op);

block = self.assert(block, Operand::Move(of), false,
AssertMessage::Math(err), span);
Expand All @@ -331,11 +322,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// and 2. there are two possible failure cases, divide-by-zero and overflow.

let (zero_err, overflow_err) = if op == BinOp::Div {
(ConstMathErr::DivisionByZero,
ConstMathErr::Overflow(Op::Div))
(EvalErrorKind::DivisionByZero,
EvalErrorKind::Overflow(op))
} else {
(ConstMathErr::RemainderByZero,
ConstMathErr::Overflow(Op::Rem))
(EvalErrorKind::RemainderByZero,
EvalErrorKind::Overflow(op))
};

// Check for / 0
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/interpret/eval_context.rs
Expand Up @@ -513,7 +513,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
// it emits in debug mode) is performance, but it doesn't cost us any performance in miri.
// If, however, the compiler ever starts transforming unchecked intrinsics into unchecked binops,
// we have to go back to just ignoring the overflow here.
return err!(OverflowingMath);
return err!(Overflow(bin_op));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/interpret/operator.rs
Expand Up @@ -269,7 +269,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
(Neg, ty::TyFloat(FloatTy::F32)) => Single::to_bits(-Single::from_bits(bytes)),
(Neg, ty::TyFloat(FloatTy::F64)) => Double::to_bits(-Double::from_bits(bytes)),

(Neg, _) if bytes == (1 << (size - 1)) => return err!(OverflowingMath),
(Neg, _) if bytes == (1 << (size - 1)) => return err!(OverflowNeg),
(Neg, _) => (-(bytes as i128)) as u128,
};

Expand Down

0 comments on commit cefcf05

Please sign in to comment.