Skip to content

Commit cefcf05

Browse files
committed
Merge ConstMathError into EvalErrorKind
1 parent 671b2a5 commit cefcf05

File tree

12 files changed

+65
-115
lines changed

12 files changed

+65
-115
lines changed

src/librustc/ich/impls_ty.rs

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -525,16 +525,26 @@ impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
525525
predicates
526526
});
527527

528+
528529
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
529530
for ::mir::interpret::EvalError<'gcx> {
531+
fn hash_stable<W: StableHasherResult>(&self,
532+
hcx: &mut StableHashingContext<'a>,
533+
hasher: &mut StableHasher<W>) {
534+
self.kind.hash_stable(hcx, hasher)
535+
}
536+
}
537+
538+
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
539+
for ::mir::interpret::EvalErrorKind<'gcx> {
530540
fn hash_stable<W: StableHasherResult>(&self,
531541
hcx: &mut StableHashingContext<'a>,
532542
hasher: &mut StableHasher<W>) {
533543
use mir::interpret::EvalErrorKind::*;
534544

535-
mem::discriminant(&self.kind).hash_stable(hcx, hasher);
545+
mem::discriminant(&self).hash_stable(hcx, hasher);
536546

537-
match self.kind {
547+
match *self {
538548
DanglingPointerDeref |
539549
DoubleFree |
540550
InvalidMemoryAccess |
@@ -565,8 +575,10 @@ for ::mir::interpret::EvalError<'gcx> {
565575
TypeckError |
566576
DerefFunctionPointer |
567577
ExecuteMemory |
568-
ReferencedConstant |
569-
OverflowingMath => {}
578+
OverflowNeg |
579+
RemainderByZero |
580+
DivisionByZero |
581+
ReferencedConstant => {}
570582
MachineError(ref err) => err.hash_stable(hcx, hasher),
571583
FunctionPointerTyMismatch(a, b) => {
572584
a.hash_stable(hcx, hasher);
@@ -590,10 +602,6 @@ for ::mir::interpret::EvalError<'gcx> {
590602
a.hash_stable(hcx, hasher);
591603
b.hash_stable(hcx, hasher)
592604
},
593-
Math(sp, ref err) => {
594-
sp.hash_stable(hcx, hasher);
595-
err.hash_stable(hcx, hasher)
596-
},
597605
Intrinsic(ref s) => s.hash_stable(hcx, hasher),
598606
InvalidChar(c) => c.hash_stable(hcx, hasher),
599607
AbiViolation(ref s) => s.hash_stable(hcx, hasher),
@@ -665,27 +673,11 @@ for ::mir::interpret::EvalError<'gcx> {
665673
Layout(lay) => lay.hash_stable(hcx, hasher),
666674
HeapAllocNonPowerOfTwoAlignment(n) => n.hash_stable(hcx, hasher),
667675
PathNotFound(ref v) => v.hash_stable(hcx, hasher),
676+
Overflow(op) => op.hash_stable(hcx, hasher),
668677
}
669678
}
670679
}
671680

672-
impl_stable_hash_for!(enum mir::interpret::ConstMathErr {
673-
Overflow(op),
674-
DivisionByZero,
675-
RemainderByZero,
676-
});
677-
678-
impl_stable_hash_for!(enum mir::interpret::Op {
679-
Add,
680-
Sub,
681-
Mul,
682-
Div,
683-
Rem,
684-
Shr,
685-
Shl,
686-
Neg,
687-
});
688-
689681
impl_stable_hash_for!(enum mir::interpret::Lock {
690682
NoLock,
691683
WriteLock(dl),

src/librustc/mir/interpret/error.rs

Lines changed: 20 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::error::Error;
21
use std::{fmt, env};
32

43
use mir;
@@ -30,7 +29,7 @@ impl<'tcx> From<EvalErrorKind<'tcx>> for EvalError<'tcx> {
3029
}
3130
}
3231

33-
#[derive(Debug, Clone)]
32+
#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
3433
pub enum EvalErrorKind<'tcx> {
3534
/// This variant is used by machines to signal their own errors that do not
3635
/// match an existing variant
@@ -60,9 +59,11 @@ pub enum EvalErrorKind<'tcx> {
6059
DerefFunctionPointer,
6160
ExecuteMemory,
6261
ArrayIndexOutOfBounds(Span, u64, u64),
63-
Math(Span, ConstMathErr),
62+
Overflow(mir::BinOp),
63+
OverflowNeg,
64+
DivisionByZero,
65+
RemainderByZero,
6466
Intrinsic(String),
65-
OverflowingMath,
6667
InvalidChar(u128),
6768
StackFrameLimitReached,
6869
OutOfTls,
@@ -124,10 +125,10 @@ pub enum EvalErrorKind<'tcx> {
124125

125126
pub type EvalResult<'tcx, T = ()> = Result<T, EvalError<'tcx>>;
126127

127-
impl<'tcx> Error for EvalError<'tcx> {
128-
fn description(&self) -> &str {
128+
impl<'tcx> EvalErrorKind<'tcx> {
129+
pub fn description(&self) -> &str {
129130
use self::EvalErrorKind::*;
130-
match self.kind {
131+
match *self {
131132
MachineError(ref inner) => inner,
132133
FunctionPointerTyMismatch(..) =>
133134
"tried to call a function through a function pointer of a different type",
@@ -176,12 +177,8 @@ impl<'tcx> Error for EvalError<'tcx> {
176177
"tried to treat a memory pointer as a function pointer",
177178
ArrayIndexOutOfBounds(..) =>
178179
"array index out of bounds",
179-
Math(..) =>
180-
"mathematical operation failed",
181180
Intrinsic(..) =>
182181
"intrinsic failed",
183-
OverflowingMath =>
184-
"attempted to do overflowing math",
185182
NoMirFor(..) =>
186183
"mir not found",
187184
InvalidChar(..) =>
@@ -239,6 +236,17 @@ impl<'tcx> Error for EvalError<'tcx> {
239236
"encountered constants with type errors, stopping evaluation",
240237
ReferencedConstant =>
241238
"referenced constant has errors",
239+
Overflow(mir::BinOp::Add) => "attempt to add with overflow",
240+
Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",
241+
Overflow(mir::BinOp::Mul) => "attempt to multiply with overflow",
242+
Overflow(mir::BinOp::Div) => "attempt to divide with overflow",
243+
Overflow(mir::BinOp::Rem) => "attempt to calculate the remainder with overflow",
244+
OverflowNeg => "attempt to negate with overflow",
245+
Overflow(mir::BinOp::Shr) => "attempt to shift right with overflow",
246+
Overflow(mir::BinOp::Shl) => "attempt to shift left with overflow",
247+
Overflow(op) => bug!("{:?} cannot overflow", op),
248+
DivisionByZero => "attempt to divide by zero",
249+
RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
242250
}
243251
}
244252
}
@@ -280,8 +288,6 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
280288
write!(f, "tried to reallocate memory from {} to {}", old, new),
281289
DeallocatedWrongMemoryKind(ref old, ref new) =>
282290
write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new),
283-
Math(_, ref err) =>
284-
write!(f, "{}", err.description()),
285291
Intrinsic(ref err) =>
286292
write!(f, "{}", err),
287293
InvalidChar(c) =>
@@ -299,45 +305,7 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
299305
write!(f, "{}", inner),
300306
IncorrectAllocationInformation(size, size2, align, align2) =>
301307
write!(f, "incorrect alloc info: expected size {} and align {}, got size {} and align {}", size, align, size2, align2),
302-
_ => write!(f, "{}", self.description()),
303-
}
304-
}
305-
}
306-
307-
#[derive(Debug, PartialEq, Eq, Clone, RustcEncodable, RustcDecodable)]
308-
pub enum ConstMathErr {
309-
Overflow(Op),
310-
DivisionByZero,
311-
RemainderByZero,
312-
}
313-
pub use self::ConstMathErr::*;
314-
315-
#[derive(Debug, PartialEq, Eq, Clone, RustcEncodable, RustcDecodable)]
316-
pub enum Op {
317-
Add,
318-
Sub,
319-
Mul,
320-
Div,
321-
Rem,
322-
Shr,
323-
Shl,
324-
Neg,
325-
}
326-
327-
impl ConstMathErr {
328-
pub fn description(&self) -> &'static str {
329-
use self::Op::*;
330-
match *self {
331-
Overflow(Add) => "attempt to add with overflow",
332-
Overflow(Sub) => "attempt to subtract with overflow",
333-
Overflow(Mul) => "attempt to multiply with overflow",
334-
Overflow(Div) => "attempt to divide with overflow",
335-
Overflow(Rem) => "attempt to calculate the remainder with overflow",
336-
Overflow(Neg) => "attempt to negate with overflow",
337-
Overflow(Shr) => "attempt to shift right with overflow",
338-
Overflow(Shl) => "attempt to shift left with overflow",
339-
DivisionByZero => "attempt to divide by zero",
340-
RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
308+
_ => write!(f, "{}", self.kind.description()),
341309
}
342310
}
343311
}

src/librustc/mir/interpret/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ macro_rules! err {
88
mod error;
99
mod value;
1010

11-
pub use self::error::{EvalError, EvalResult, EvalErrorKind, Op, ConstMathErr};
11+
pub use self::error::{EvalError, EvalResult, EvalErrorKind};
1212

1313
pub use self::value::{PrimVal, PrimValKind, Value, Pointer};
1414

@@ -23,21 +23,21 @@ use std::iter;
2323
use syntax::ast::Mutability;
2424
use rustc_serialize::{Encoder, Decoder, Decodable, Encodable};
2525

26-
#[derive(Clone, Debug, PartialEq)]
26+
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
2727
pub enum Lock {
2828
NoLock,
2929
WriteLock(DynamicLifetime),
3030
/// This should never be empty -- that would be a read lock held and nobody there to release it...
3131
ReadLock(Vec<DynamicLifetime>),
3232
}
3333

34-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
34+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
3535
pub struct DynamicLifetime {
3636
pub frame: usize,
3737
pub region: Option<region::Scope>, // "None" indicates "until the function ends"
3838
}
3939

40-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
40+
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
4141
pub enum AccessKind {
4242
Read,
4343
Write,
@@ -88,12 +88,12 @@ pub trait PointerArithmetic: layout::HasDataLayout {
8888

8989
fn signed_offset<'tcx>(self, val: u64, i: i64) -> EvalResult<'tcx, u64> {
9090
let (res, over) = self.overflowing_signed_offset(val, i as i128);
91-
if over { err!(OverflowingMath) } else { Ok(res) }
91+
if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
9292
}
9393

9494
fn offset<'tcx>(self, val: u64, i: u64) -> EvalResult<'tcx, u64> {
9595
let (res, over) = self.overflowing_offset(val, i);
96-
if over { err!(OverflowingMath) } else { Ok(res) }
96+
if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
9797
}
9898

9999
fn wrapping_signed_offset(self, val: u64, i: i64) -> u64 {

src/librustc/mir/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_serialize as serialize;
2525
use hir::def::CtorKind;
2626
use hir::def_id::DefId;
2727
use mir::visit::MirVisitable;
28-
use mir::interpret::{Value, PrimVal, ConstMathErr};
28+
use mir::interpret::{Value, PrimVal, EvalErrorKind};
2929
use ty::subst::{Subst, Substs};
3030
use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, Region, Ty, TyCtxt, GeneratorInterior};
3131
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
@@ -1211,7 +1211,7 @@ pub enum AssertMessage<'tcx> {
12111211
len: Operand<'tcx>,
12121212
index: Operand<'tcx>
12131213
},
1214-
Math(ConstMathErr),
1214+
Math(EvalErrorKind<'tcx>),
12151215
GeneratorResumedAfterReturn,
12161216
GeneratorResumedAfterPanic,
12171217
}
@@ -1920,9 +1920,9 @@ pub fn print_miri_value<W: Write>(value: Value, ty: Ty, f: &mut W) -> fmt::Resul
19201920
(Value::ByVal(PrimVal::Bytes(0)), &TyBool) => write!(f, "false"),
19211921
(Value::ByVal(PrimVal::Bytes(1)), &TyBool) => write!(f, "true"),
19221922
(Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F32)) =>
1923-
write!(f, "{}", Single::from_bits(bits)),
1923+
write!(f, "{}f32", Single::from_bits(bits)),
19241924
(Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F64)) =>
1925-
write!(f, "{}", Double::from_bits(bits)),
1925+
write!(f, "{}f64", Double::from_bits(bits)),
19261926
(Value::ByVal(PrimVal::Bytes(n)), &TyUint(ui)) => write!(f, "{:?}{}", n, ui),
19271927
(Value::ByVal(PrimVal::Bytes(n)), &TyInt(i)) => write!(f, "{:?}{}", n as i128, i),
19281928
(Value::ByVal(PrimVal::Bytes(n)), &TyChar) =>

src/librustc/ty/layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ pub const FAT_PTR_ADDR: usize = 0;
149149
/// - For a slice, this is the length.
150150
pub const FAT_PTR_EXTRA: usize = 1;
151151

152-
#[derive(Copy, Clone, Debug)]
152+
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
153153
pub enum LayoutError<'tcx> {
154154
Unknown(Ty<'tcx>),
155155
SizeOverflow(Ty<'tcx>)

src/librustc/ty/structural_impls.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,9 +505,7 @@ impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
505505
DerefFunctionPointer => DerefFunctionPointer,
506506
ExecuteMemory => ExecuteMemory,
507507
ArrayIndexOutOfBounds(sp, a, b) => ArrayIndexOutOfBounds(sp, a, b),
508-
Math(sp, ref err) => Math(sp, err.clone()),
509508
Intrinsic(ref s) => Intrinsic(s.clone()),
510-
OverflowingMath => OverflowingMath,
511509
InvalidChar(c) => InvalidChar(c),
512510
StackFrameLimitReached => StackFrameLimitReached,
513511
OutOfTls => OutOfTls,
@@ -568,6 +566,10 @@ impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
568566
UnimplementedTraitSelection => UnimplementedTraitSelection,
569567
TypeckError => TypeckError,
570568
ReferencedConstant => ReferencedConstant,
569+
OverflowNeg => OverflowNeg,
570+
Overflow(op) => Overflow(op),
571+
DivisionByZero => DivisionByZero,
572+
RemainderByZero => RemainderByZero,
571573
};
572574
Some(interpret::EvalError {
573575
kind: kind,

src/librustc_mir/build/expr/as_rvalue.rs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc::middle::const_val::ConstVal;
2020
use rustc::middle::region;
2121
use rustc::ty::{self, Ty};
2222
use rustc::mir::*;
23-
use rustc::mir::interpret::{Value, PrimVal, ConstMathErr, Op};
23+
use rustc::mir::interpret::{Value, PrimVal, EvalErrorKind};
2424
use syntax_pos::Span;
2525

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

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

313-
let err = ConstMathErr::Overflow(match op {
314-
BinOp::Add => Op::Add,
315-
BinOp::Sub => Op::Sub,
316-
BinOp::Mul => Op::Mul,
317-
BinOp::Shl => Op::Shl,
318-
BinOp::Shr => Op::Shr,
319-
_ => {
320-
bug!("MIR build_binary_op: {:?} is not checkable", op)
321-
}
322-
});
313+
let err = EvalErrorKind::Overflow(op);
323314

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

333324
let (zero_err, overflow_err) = if op == BinOp::Div {
334-
(ConstMathErr::DivisionByZero,
335-
ConstMathErr::Overflow(Op::Div))
325+
(EvalErrorKind::DivisionByZero,
326+
EvalErrorKind::Overflow(op))
336327
} else {
337-
(ConstMathErr::RemainderByZero,
338-
ConstMathErr::Overflow(Op::Rem))
328+
(EvalErrorKind::RemainderByZero,
329+
EvalErrorKind::Overflow(op))
339330
};
340331

341332
// Check for / 0

src/librustc_mir/interpret/eval_context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
513513
// it emits in debug mode) is performance, but it doesn't cost us any performance in miri.
514514
// If, however, the compiler ever starts transforming unchecked intrinsics into unchecked binops,
515515
// we have to go back to just ignoring the overflow here.
516-
return err!(OverflowingMath);
516+
return err!(Overflow(bin_op));
517517
}
518518
}
519519

src/librustc_mir/interpret/operator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
269269
(Neg, ty::TyFloat(FloatTy::F32)) => Single::to_bits(-Single::from_bits(bytes)),
270270
(Neg, ty::TyFloat(FloatTy::F64)) => Double::to_bits(-Double::from_bits(bytes)),
271271

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

0 commit comments

Comments
 (0)