Skip to content

Commit 01158ea

Browse files
committed
Unify MIR assert messages and const eval errors
1 parent 5f46e5c commit 01158ea

File tree

16 files changed

+111
-147
lines changed

16 files changed

+111
-147
lines changed

src/librustc/ich/impls_mir.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -227,27 +227,6 @@ for mir::TerminatorKind<'gcx> {
227227
}
228228
}
229229

230-
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
231-
for mir::AssertMessage<'gcx> {
232-
fn hash_stable<W: StableHasherResult>(&self,
233-
hcx: &mut StableHashingContext<'a>,
234-
hasher: &mut StableHasher<W>) {
235-
mem::discriminant(self).hash_stable(hcx, hasher);
236-
237-
match *self {
238-
mir::AssertMessage::BoundsCheck { ref len, ref index } => {
239-
len.hash_stable(hcx, hasher);
240-
index.hash_stable(hcx, hasher);
241-
}
242-
mir::AssertMessage::Math(ref const_math_err) => {
243-
const_math_err.hash_stable(hcx, hasher);
244-
}
245-
mir::AssertMessage::GeneratorResumedAfterReturn => (),
246-
mir::AssertMessage::GeneratorResumedAfterPanic => (),
247-
}
248-
}
249-
}
250-
251230
impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
252231

253232
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>

src/librustc/ich/impls_ty.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -535,8 +535,8 @@ for ::mir::interpret::EvalError<'gcx> {
535535
}
536536
}
537537

538-
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
539-
for ::mir::interpret::EvalErrorKind<'gcx> {
538+
impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
539+
for ::mir::interpret::EvalErrorKind<'gcx, O> {
540540
fn hash_stable<W: StableHasherResult>(&self,
541541
hcx: &mut StableHashingContext<'a>,
542542
hasher: &mut StableHasher<W>) {
@@ -578,6 +578,8 @@ for ::mir::interpret::EvalErrorKind<'gcx> {
578578
OverflowNeg |
579579
RemainderByZero |
580580
DivisionByZero |
581+
GeneratorResumedAfterReturn |
582+
GeneratorResumedAfterPanic |
581583
ReferencedConstant => {}
582584
MachineError(ref err) => err.hash_stable(hcx, hasher),
583585
FunctionPointerTyMismatch(a, b) => {
@@ -597,10 +599,9 @@ for ::mir::interpret::EvalErrorKind<'gcx> {
597599
},
598600
InvalidBoolOp(bop) => bop.hash_stable(hcx, hasher),
599601
Unimplemented(ref s) => s.hash_stable(hcx, hasher),
600-
ArrayIndexOutOfBounds(sp, a, b) => {
601-
sp.hash_stable(hcx, hasher);
602-
a.hash_stable(hcx, hasher);
603-
b.hash_stable(hcx, hasher)
602+
BoundsCheck { ref len, ref index } => {
603+
len.hash_stable(hcx, hasher);
604+
index.hash_stable(hcx, hasher)
604605
},
605606
Intrinsic(ref s) => s.hash_stable(hcx, hasher),
606607
InvalidChar(c) => c.hash_stable(hcx, hasher),

src/librustc/mir/interpret/error.rs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,16 @@ use super::{
77
MemoryPointer, Lock, AccessKind
88
};
99

10-
use syntax::codemap::Span;
1110
use backtrace::Backtrace;
1211

1312
#[derive(Debug, Clone)]
1413
pub struct EvalError<'tcx> {
15-
pub kind: EvalErrorKind<'tcx>,
14+
pub kind: EvalErrorKind<'tcx, u64>,
1615
pub backtrace: Option<Backtrace>,
1716
}
1817

19-
impl<'tcx> From<EvalErrorKind<'tcx>> for EvalError<'tcx> {
20-
fn from(kind: EvalErrorKind<'tcx>) -> Self {
18+
impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
19+
fn from(kind: EvalErrorKind<'tcx, u64>) -> Self {
2120
let backtrace = match env::var("MIRI_BACKTRACE") {
2221
Ok(ref val) if !val.is_empty() => Some(Backtrace::new_unresolved()),
2322
_ => None
@@ -29,8 +28,10 @@ impl<'tcx> From<EvalErrorKind<'tcx>> for EvalError<'tcx> {
2928
}
3029
}
3130

32-
#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
33-
pub enum EvalErrorKind<'tcx> {
31+
pub type AssertMessage<'tcx> = EvalErrorKind<'tcx, mir::Operand<'tcx>>;
32+
33+
#[derive(Clone, RustcEncodable, RustcDecodable)]
34+
pub enum EvalErrorKind<'tcx, O> {
3435
/// This variant is used by machines to signal their own errors that do not
3536
/// match an existing variant
3637
MachineError(String),
@@ -58,7 +59,7 @@ pub enum EvalErrorKind<'tcx> {
5859
Unimplemented(String),
5960
DerefFunctionPointer,
6061
ExecuteMemory,
61-
ArrayIndexOutOfBounds(Span, u64, u64),
62+
BoundsCheck { len: O, index: O },
6263
Overflow(mir::BinOp),
6364
OverflowNeg,
6465
DivisionByZero,
@@ -121,11 +122,13 @@ pub enum EvalErrorKind<'tcx> {
121122
/// Cannot compute this constant because it depends on another one
122123
/// which already produced an error
123124
ReferencedConstant,
125+
GeneratorResumedAfterReturn,
126+
GeneratorResumedAfterPanic,
124127
}
125128

126129
pub type EvalResult<'tcx, T = ()> = Result<T, EvalError<'tcx>>;
127130

128-
impl<'tcx> EvalErrorKind<'tcx> {
131+
impl<'tcx, O> EvalErrorKind<'tcx, O> {
129132
pub fn description(&self) -> &str {
130133
use self::EvalErrorKind::*;
131134
match *self {
@@ -175,7 +178,7 @@ impl<'tcx> EvalErrorKind<'tcx> {
175178
"tried to dereference a function pointer",
176179
ExecuteMemory =>
177180
"tried to treat a memory pointer as a function pointer",
178-
ArrayIndexOutOfBounds(..) =>
181+
BoundsCheck{..} =>
179182
"array index out of bounds",
180183
Intrinsic(..) =>
181184
"intrinsic failed",
@@ -228,7 +231,7 @@ impl<'tcx> EvalErrorKind<'tcx> {
228231
"the evaluated program panicked",
229232
ReadFromReturnPointer =>
230233
"tried to read from the return pointer",
231-
EvalErrorKind::PathNotFound(_) =>
234+
PathNotFound(_) =>
232235
"a path could not be resolved, maybe the crate is not loaded",
233236
UnimplementedTraitSelection =>
234237
"there were unresolved type arguments during trait selection",
@@ -247,14 +250,22 @@ impl<'tcx> EvalErrorKind<'tcx> {
247250
Overflow(op) => bug!("{:?} cannot overflow", op),
248251
DivisionByZero => "attempt to divide by zero",
249252
RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
253+
GeneratorResumedAfterReturn => "generator resumed after completion",
254+
GeneratorResumedAfterPanic => "generator resumed after panicking",
250255
}
251256
}
252257
}
253258

254259
impl<'tcx> fmt::Display for EvalError<'tcx> {
260+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
261+
write!(f, "{:?}", self.kind)
262+
}
263+
}
264+
265+
impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> {
255266
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
256267
use self::EvalErrorKind::*;
257-
match self.kind {
268+
match *self {
258269
PointerOutOfBounds { ptr, access, allocation_size } => {
259270
write!(f, "{} at offset {}, outside bounds of allocation {} which has size {}",
260271
if access { "memory access" } else { "pointer computed" },
@@ -282,8 +293,8 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
282293
NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
283294
FunctionPointerTyMismatch(sig, got) =>
284295
write!(f, "tried to call a function with sig {} through a function pointer of type {}", sig, got),
285-
ArrayIndexOutOfBounds(span, len, index) =>
286-
write!(f, "index out of bounds: the len is {} but the index is {} at {:?}", len, index, span),
296+
BoundsCheck { ref len, ref index } =>
297+
write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
287298
ReallocatedWrongMemoryKind(ref old, ref new) =>
288299
write!(f, "tried to reallocate memory from {} to {}", old, new),
289300
DeallocatedWrongMemoryKind(ref old, ref new) =>
@@ -305,7 +316,7 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
305316
write!(f, "{}", inner),
306317
IncorrectAllocationInformation(size, size2, align, align2) =>
307318
write!(f, "incorrect alloc info: expected size {} and align {}, got size {} and align {}", size, align, size2, align2),
308-
_ => write!(f, "{}", self.kind.description()),
319+
_ => write!(f, "{}", self.description()),
309320
}
310321
}
311322
}

src/librustc/mir/interpret/mod.rs

Lines changed: 1 addition & 1 deletion
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};
11+
pub use self::error::{EvalError, EvalResult, EvalErrorKind, AssertMessage};
1212

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

src/librustc/mir/mod.rs

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ use syntax_pos::{Span, DUMMY_SP};
4545
use rustc_apfloat::ieee::{Single, Double};
4646
use rustc_apfloat::Float;
4747

48+
pub use mir::interpret::AssertMessage;
49+
4850
mod cache;
4951
pub mod tcx;
5052
pub mod visit;
@@ -1132,23 +1134,7 @@ impl<'tcx> TerminatorKind<'tcx> {
11321134
write!(fmt, "!")?;
11331135
}
11341136
write!(fmt, "{:?}, ", cond)?;
1135-
1136-
match *msg {
1137-
AssertMessage::BoundsCheck { ref len, ref index } => {
1138-
write!(fmt, "{:?}, {:?}, {:?}",
1139-
"index out of bounds: the len is {} but the index is {}",
1140-
len, index)?;
1141-
}
1142-
AssertMessage::Math(ref err) => {
1143-
write!(fmt, "{:?}", err.description())?;
1144-
}
1145-
AssertMessage::GeneratorResumedAfterReturn => {
1146-
write!(fmt, "{:?}", "generator resumed after completion")?;
1147-
}
1148-
AssertMessage::GeneratorResumedAfterPanic => {
1149-
write!(fmt, "{:?}", "generator resumed after panicking")?;
1150-
}
1151-
}
1137+
write!(fmt, "{:?}", msg)?;
11521138

11531139
write!(fmt, ")")
11541140
},
@@ -1205,17 +1191,6 @@ impl<'tcx> TerminatorKind<'tcx> {
12051191
}
12061192
}
12071193

1208-
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
1209-
pub enum AssertMessage<'tcx> {
1210-
BoundsCheck {
1211-
len: Operand<'tcx>,
1212-
index: Operand<'tcx>
1213-
},
1214-
Math(EvalErrorKind<'tcx>),
1215-
GeneratorResumedAfterReturn,
1216-
GeneratorResumedAfterPanic,
1217-
}
1218-
12191194
///////////////////////////////////////////////////////////////////////////
12201195
// Statements
12211196

@@ -2281,8 +2256,8 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
22812256
}
22822257
},
22832258
Assert { ref cond, expected, ref msg, target, cleanup } => {
2284-
let msg = if let AssertMessage::BoundsCheck { ref len, ref index } = *msg {
2285-
AssertMessage::BoundsCheck {
2259+
let msg = if let EvalErrorKind::BoundsCheck { ref len, ref index } = *msg {
2260+
EvalErrorKind::BoundsCheck {
22862261
len: len.fold_with(folder),
22872262
index: index.fold_with(folder),
22882263
}
@@ -2331,7 +2306,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
23312306
},
23322307
Assert { ref cond, ref msg, .. } => {
23332308
if cond.visit_with(visitor) {
2334-
if let AssertMessage::BoundsCheck { ref len, ref index } = *msg {
2309+
if let EvalErrorKind::BoundsCheck { ref len, ref index } = *msg {
23352310
len.visit_with(visitor) || index.visit_with(visitor)
23362311
} else {
23372312
false

src/librustc/mir/visit.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -511,17 +511,13 @@ macro_rules! make_mir_visitor {
511511
fn super_assert_message(&mut self,
512512
msg: & $($mutability)* AssertMessage<'tcx>,
513513
location: Location) {
514-
match *msg {
515-
AssertMessage::BoundsCheck {
514+
use mir::interpret::EvalErrorKind::*;
515+
if let BoundsCheck {
516516
ref $($mutability)* len,
517517
ref $($mutability)* index
518-
} => {
519-
self.visit_operand(len, location);
520-
self.visit_operand(index, location);
521-
}
522-
AssertMessage::Math(_) => {},
523-
AssertMessage::GeneratorResumedAfterReturn => {},
524-
AssertMessage::GeneratorResumedAfterPanic => {},
518+
} = *msg {
519+
self.visit_operand(len, location);
520+
self.visit_operand(index, location);
525521
}
526522
}
527523

src/librustc/ty/structural_impls.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,19 @@ impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> {
473473

474474
impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
475475
type Lifted = interpret::EvalError<'tcx>;
476+
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
477+
Some(interpret::EvalError {
478+
kind: tcx.lift(&self.kind)?,
479+
backtrace: self.backtrace.clone(),
480+
})
481+
}
482+
}
483+
484+
impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> {
485+
type Lifted = interpret::EvalErrorKind<'tcx, <O as Lift<'tcx>>::Lifted>;
476486
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
477487
use ::mir::interpret::EvalErrorKind::*;
478-
let kind = match self.kind {
488+
Some(match *self {
479489
MachineError(ref err) => MachineError(err.clone()),
480490
FunctionPointerTyMismatch(a, b) => FunctionPointerTyMismatch(
481491
tcx.lift(&a)?,
@@ -504,7 +514,10 @@ impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
504514
Unimplemented(ref s) => Unimplemented(s.clone()),
505515
DerefFunctionPointer => DerefFunctionPointer,
506516
ExecuteMemory => ExecuteMemory,
507-
ArrayIndexOutOfBounds(sp, a, b) => ArrayIndexOutOfBounds(sp, a, b),
517+
BoundsCheck { ref len, ref index } => BoundsCheck {
518+
len: tcx.lift(len)?,
519+
index: tcx.lift(index)?,
520+
},
508521
Intrinsic(ref s) => Intrinsic(s.clone()),
509522
InvalidChar(c) => InvalidChar(c),
510523
StackFrameLimitReached => StackFrameLimitReached,
@@ -570,10 +583,8 @@ impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
570583
Overflow(op) => Overflow(op),
571584
DivisionByZero => DivisionByZero,
572585
RemainderByZero => RemainderByZero,
573-
};
574-
Some(interpret::EvalError {
575-
kind: kind,
576-
backtrace: self.backtrace.clone(),
586+
GeneratorResumedAfterReturn => GeneratorResumedAfterReturn,
587+
GeneratorResumedAfterPanic => GeneratorResumedAfterPanic,
577588
})
578589
}
579590
}

src/librustc_mir/borrow_check/mod.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc::infer::InferCtxt;
1818
use rustc::ty::{self, ParamEnv, TyCtxt};
1919
use rustc::ty::maps::Providers;
2020
use rustc::lint::builtin::UNUSED_MUT;
21-
use rustc::mir::{AssertMessage, AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
21+
use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
2222
use rustc::mir::{ClearCrossCrate, Local, Location, Place, Mir, Mutability, Operand};
2323
use rustc::mir::{Projection, ProjectionElem, Rvalue, Field, Statement, StatementKind};
2424
use rustc::mir::{Terminator, TerminatorKind};
@@ -586,18 +586,14 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
586586
cleanup: _,
587587
} => {
588588
self.consume_operand(ContextKind::Assert.new(loc), (cond, span), flow_state);
589-
match *msg {
590-
AssertMessage::BoundsCheck { ref len, ref index } => {
591-
self.consume_operand(ContextKind::Assert.new(loc), (len, span), flow_state);
592-
self.consume_operand(
593-
ContextKind::Assert.new(loc),
594-
(index, span),
595-
flow_state,
596-
);
597-
}
598-
AssertMessage::Math(_ /*const_math_err*/) => {}
599-
AssertMessage::GeneratorResumedAfterReturn => {}
600-
AssertMessage::GeneratorResumedAfterPanic => {}
589+
use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
590+
if let BoundsCheck { ref len, ref index } = *msg {
591+
self.consume_operand(ContextKind::Assert.new(loc), (len, span), flow_state);
592+
self.consume_operand(
593+
ContextKind::Assert.new(loc),
594+
(index, span),
595+
flow_state,
596+
);
601597
}
602598
}
603599

src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc::infer::region_constraints::{GenericKind, RegionConstraintData};
2222
use rustc::infer::{InferCtxt, InferOk, InferResult, LateBoundRegionConversionTime, UnitResult};
2323
use rustc::mir::tcx::PlaceTy;
2424
use rustc::mir::visit::{PlaceContext, Visitor};
25+
use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
2526
use rustc::mir::*;
2627
use rustc::traits::query::NoSolution;
2728
use rustc::traits::{self, Normalized, TraitEngine};
@@ -928,7 +929,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
928929
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
929930
}
930931

931-
if let AssertMessage::BoundsCheck { ref len, ref index } = *msg {
932+
if let BoundsCheck { ref len, ref index } = *msg {
932933
if len.ty(mir, tcx) != tcx.types.usize {
933934
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
934935
}

0 commit comments

Comments
 (0)