Skip to content

Commit 52e9e44

Browse files
Rollup merge of rust-lang#60951 - saleemjaffer:mir_better_error_enum, r=oli-obk
more specific errors in src/librustc/mir/interpret/error.rs Implements [this](rust-lang/const-eval#4)
2 parents 3ebca72 + 3730ed9 commit 52e9e44

File tree

16 files changed

+105
-86
lines changed

16 files changed

+105
-86
lines changed

src/librustc/mir/interpret/error.rs

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,24 @@ impl<'tcx> From<InterpError<'tcx, u64>> for InterpErrorInfo<'tcx> {
228228

229229
pub type AssertMessage<'tcx> = InterpError<'tcx, mir::Operand<'tcx>>;
230230

231+
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
232+
pub enum PanicMessage<O> {
233+
Panic {
234+
msg: Symbol,
235+
line: u32,
236+
col: u32,
237+
file: Symbol,
238+
},
239+
BoundsCheck {
240+
len: O,
241+
index: O,
242+
},
243+
Overflow(mir::BinOp),
244+
OverflowNeg,
245+
DivisionByZero,
246+
RemainderByZero,
247+
}
248+
231249
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
232250
pub enum InterpError<'tcx, O> {
233251
/// This variant is used by machines to signal their own errors that do not
@@ -266,11 +284,6 @@ pub enum InterpError<'tcx, O> {
266284
Unimplemented(String),
267285
DerefFunctionPointer,
268286
ExecuteMemory,
269-
BoundsCheck { len: O, index: O },
270-
Overflow(mir::BinOp),
271-
OverflowNeg,
272-
DivisionByZero,
273-
RemainderByZero,
274287
Intrinsic(String),
275288
InvalidChar(u128),
276289
StackFrameLimitReached,
@@ -298,12 +311,7 @@ pub enum InterpError<'tcx, O> {
298311
HeapAllocZeroBytes,
299312
HeapAllocNonPowerOfTwoAlignment(u64),
300313
Unreachable,
301-
Panic {
302-
msg: Symbol,
303-
line: u32,
304-
col: u32,
305-
file: Symbol,
306-
},
314+
Panic(PanicMessage<O>),
307315
ReadFromReturnPointer,
308316
PathNotFound(Vec<String>),
309317
UnimplementedTraitSelection,
@@ -369,8 +377,6 @@ impl<'tcx, O> InterpError<'tcx, O> {
369377
"tried to dereference a function pointer",
370378
ExecuteMemory =>
371379
"tried to treat a memory pointer as a function pointer",
372-
BoundsCheck{..} =>
373-
"array index out of bounds",
374380
Intrinsic(..) =>
375381
"intrinsic failed",
376382
NoMirFor(..) =>
@@ -422,8 +428,32 @@ impl<'tcx, O> InterpError<'tcx, O> {
422428
two",
423429
Unreachable =>
424430
"entered unreachable code",
425-
Panic { .. } =>
431+
Panic(PanicMessage::Panic{..}) =>
426432
"the evaluated program panicked",
433+
Panic(PanicMessage::BoundsCheck{..}) =>
434+
"array index out of bounds",
435+
Panic(PanicMessage::Overflow(mir::BinOp::Add)) =>
436+
"attempt to add with overflow",
437+
Panic(PanicMessage::Overflow(mir::BinOp::Sub)) =>
438+
"attempt to subtract with overflow",
439+
Panic(PanicMessage::Overflow(mir::BinOp::Mul)) =>
440+
"attempt to multiply with overflow",
441+
Panic(PanicMessage::Overflow(mir::BinOp::Div)) =>
442+
"attempt to divide with overflow",
443+
Panic(PanicMessage::Overflow(mir::BinOp::Rem)) =>
444+
"attempt to calculate the remainder with overflow",
445+
Panic(PanicMessage::OverflowNeg) =>
446+
"attempt to negate with overflow",
447+
Panic(PanicMessage::Overflow(mir::BinOp::Shr)) =>
448+
"attempt to shift right with overflow",
449+
Panic(PanicMessage::Overflow(mir::BinOp::Shl)) =>
450+
"attempt to shift left with overflow",
451+
Panic(PanicMessage::Overflow(op)) =>
452+
bug!("{:?} cannot overflow", op),
453+
Panic(PanicMessage::DivisionByZero) =>
454+
"attempt to divide by zero",
455+
Panic(PanicMessage::RemainderByZero) =>
456+
"attempt to calculate the remainder with a divisor of zero",
427457
ReadFromReturnPointer =>
428458
"tried to read from the return pointer",
429459
PathNotFound(_) =>
@@ -436,17 +466,6 @@ impl<'tcx, O> InterpError<'tcx, O> {
436466
"encountered overly generic constant",
437467
ReferencedConstant =>
438468
"referenced constant has errors",
439-
Overflow(mir::BinOp::Add) => "attempt to add with overflow",
440-
Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",
441-
Overflow(mir::BinOp::Mul) => "attempt to multiply with overflow",
442-
Overflow(mir::BinOp::Div) => "attempt to divide with overflow",
443-
Overflow(mir::BinOp::Rem) => "attempt to calculate the remainder with overflow",
444-
OverflowNeg => "attempt to negate with overflow",
445-
Overflow(mir::BinOp::Shr) => "attempt to shift right with overflow",
446-
Overflow(mir::BinOp::Shl) => "attempt to shift left with overflow",
447-
Overflow(op) => bug!("{:?} cannot overflow", op),
448-
DivisionByZero => "attempt to divide by zero",
449-
RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
450469
GeneratorResumedAfterReturn => "generator resumed after completion",
451470
GeneratorResumedAfterPanic => "generator resumed after panicking",
452471
InfiniteLoop =>
@@ -493,8 +512,6 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> {
493512
callee_ty, caller_ty),
494513
FunctionArgCountMismatch =>
495514
write!(f, "tried to call a function with incorrect number of arguments"),
496-
BoundsCheck { ref len, ref index } =>
497-
write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
498515
ReallocatedWrongMemoryKind(ref old, ref new) =>
499516
write!(f, "tried to reallocate memory from {} to {}", old, new),
500517
DeallocatedWrongMemoryKind(ref old, ref new) =>
@@ -518,8 +535,10 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> {
518535
write!(f, "incorrect alloc info: expected size {} and align {}, \
519536
got size {} and align {}",
520537
size.bytes(), align.bytes(), size2.bytes(), align2.bytes()),
521-
Panic { ref msg, line, col, ref file } =>
538+
Panic(PanicMessage::Panic { ref msg, line, col, ref file }) =>
522539
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col),
540+
Panic(PanicMessage::BoundsCheck { ref len, ref index }) =>
541+
write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
523542
InvalidDiscriminant(val) =>
524543
write!(f, "encountered invalid enum discriminant {}", val),
525544
Exit(code) =>

src/librustc/mir/interpret/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ mod pointer;
1212

1313
pub use self::error::{
1414
InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error,
15-
FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled,
15+
FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicMessage
1616
};
1717

1818
pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue};

src/librustc/mir/interpret/pointer.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::ty::layout::{self, HasDataLayout, Size};
55
use rustc_macros::HashStable;
66

77
use super::{
8-
AllocId, InterpResult,
8+
AllocId, InterpResult, PanicMessage
99
};
1010

1111
/// Used by `check_in_alloc` to indicate context of check
@@ -76,13 +76,13 @@ pub trait PointerArithmetic: layout::HasDataLayout {
7676
#[inline]
7777
fn offset<'tcx>(&self, val: u64, i: u64) -> InterpResult<'tcx, u64> {
7878
let (res, over) = self.overflowing_offset(val, i);
79-
if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
79+
if over { err!(Panic(PanicMessage::Overflow(mir::BinOp::Add))) } else { Ok(res) }
8080
}
8181

8282
#[inline]
8383
fn signed_offset<'tcx>(&self, val: u64, i: i64) -> InterpResult<'tcx, u64> {
8484
let (res, over) = self.overflowing_signed_offset(val, i128::from(i));
85-
if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
85+
if over { err!(Panic(PanicMessage::Overflow(mir::BinOp::Add))) } else { Ok(res) }
8686
}
8787
}
8888

src/librustc/mir/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use crate::hir::def::{CtorKind, Namespace};
88
use crate::hir::def_id::DefId;
99
use crate::hir::{self, InlineAsm as HirInlineAsm};
10-
use crate::mir::interpret::{ConstValue, InterpError, Scalar};
10+
use crate::mir::interpret::{ConstValue, PanicMessage, InterpError::Panic, Scalar};
1111
use crate::mir::visit::MirVisitable;
1212
use crate::rustc_serialize as serialize;
1313
use crate::ty::adjustment::PointerCast;
@@ -3152,11 +3152,11 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
31523152
}
31533153
}
31543154
Assert { ref cond, expected, ref msg, target, cleanup } => {
3155-
let msg = if let InterpError::BoundsCheck { ref len, ref index } = *msg {
3156-
InterpError::BoundsCheck {
3155+
let msg = if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg {
3156+
Panic(PanicMessage::BoundsCheck {
31573157
len: len.fold_with(folder),
31583158
index: index.fold_with(folder),
3159-
}
3159+
})
31603160
} else {
31613161
msg.clone()
31623162
};
@@ -3197,7 +3197,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
31973197
}
31983198
Assert { ref cond, ref msg, .. } => {
31993199
if cond.visit_with(visitor) {
3200-
if let InterpError::BoundsCheck { ref len, ref index } = *msg {
3200+
if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg {
32013201
len.visit_with(visitor) || index.visit_with(visitor)
32023202
} else {
32033203
false

src/librustc/mir/visit.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,8 @@ macro_rules! make_mir_visitor {
515515
msg: & $($mutability)? AssertMessage<'tcx>,
516516
location: Location) {
517517
use crate::mir::interpret::InterpError::*;
518-
if let BoundsCheck { len, index } = msg {
518+
use crate::mir::interpret::PanicMessage::BoundsCheck;
519+
if let Panic(BoundsCheck { len, index }) = msg {
519520
self.visit_operand(len, location);
520521
self.visit_operand(index, location);
521522
}

src/librustc_codegen_ssa/mir/block.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc::middle::lang_items;
22
use rustc::ty::{self, Ty, TypeFoldable, Instance};
33
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt};
44
use rustc::mir::{self, Place, PlaceBase, Static, StaticKind};
5-
use rustc::mir::interpret::InterpError;
5+
use rustc::mir::interpret::{InterpError, PanicMessage};
66
use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode};
77
use rustc_target::spec::abi::Abi;
88
use crate::base;
@@ -368,7 +368,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
368368
// checked operation, just a comparison with the minimum
369369
// value, so we have to check for the assert message.
370370
if !bx.check_overflow() {
371-
if let mir::interpret::InterpError::OverflowNeg = *msg {
371+
if let InterpError::Panic(PanicMessage::OverflowNeg) = *msg {
372372
const_cond = Some(expected);
373373
}
374374
}
@@ -403,7 +403,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
403403

404404
// Put together the arguments to the panic entry point.
405405
let (lang_item, args) = match *msg {
406-
InterpError::BoundsCheck { ref len, ref index } => {
406+
InterpError::Panic(PanicMessage::BoundsCheck { ref len, ref index }) => {
407407
let len = self.codegen_operand(&mut bx, len).immediate();
408408
let index = self.codegen_operand(&mut bx, index).immediate();
409409

src/librustc_mir/borrow_check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -733,8 +733,8 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
733733
cleanup: _,
734734
} => {
735735
self.consume_operand(loc, (cond, span), flow_state);
736-
use rustc::mir::interpret::InterpError::BoundsCheck;
737-
if let BoundsCheck { ref len, ref index } = *msg {
736+
use rustc::mir::interpret::{InterpError::Panic, PanicMessage};
737+
if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg {
738738
self.consume_operand(loc, (len, span), flow_state);
739739
self.consume_operand(loc, (index, span), flow_state);
740740
}

src/librustc_mir/borrow_check/nll/invalidation.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
207207
cleanup: _,
208208
} => {
209209
self.consume_operand(location, cond);
210-
use rustc::mir::interpret::InterpError::BoundsCheck;
211-
if let BoundsCheck { ref len, ref index } = *msg {
210+
use rustc::mir::interpret::{InterpError::Panic, PanicMessage::BoundsCheck};
211+
if let Panic(BoundsCheck { ref len, ref index }) = *msg {
212212
self.consume_operand(location, len);
213213
self.consume_operand(location, index);
214214
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc::infer::canonical::QueryRegionConstraints;
2828
use rustc::infer::outlives::env::RegionBoundPairs;
2929
use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
3030
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
31-
use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue};
31+
use rustc::mir::interpret::{InterpError::Panic, ConstValue, PanicMessage};
3232
use rustc::mir::tcx::PlaceTy;
3333
use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext};
3434
use rustc::mir::*;
@@ -1606,7 +1606,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16061606
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
16071607
}
16081608

1609-
if let BoundsCheck { ref len, ref index } = *msg {
1609+
if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg {
16101610
if len.ty(body, tcx) != tcx.types.usize {
16111611
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
16121612
}

src/librustc_mir/build/expr/as_place.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::build::expr::category::Category;
44
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
55
use crate::build::{BlockAnd, BlockAndExtension, Builder};
66
use crate::hair::*;
7-
use rustc::mir::interpret::InterpError::BoundsCheck;
7+
use rustc::mir::interpret::{InterpError::Panic, PanicMessage::BoundsCheck};
88
use rustc::mir::*;
99
use rustc::ty::{CanonicalUserTypeAnnotation, Variance};
1010

@@ -105,10 +105,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
105105
),
106106
);
107107

108-
let msg = BoundsCheck {
108+
let msg = Panic(BoundsCheck {
109109
len: Operand::Move(len),
110110
index: Operand::Copy(Place::from(idx)),
111-
};
111+
});
112112
let success = this.assert(block, Operand::Move(lt), true, msg, expr_span);
113113
success.and(slice.index(idx))
114114
}

src/librustc_mir/build/expr/as_rvalue.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::build::expr::category::{Category, RvalueFunc};
77
use crate::build::{BlockAnd, BlockAndExtension, Builder};
88
use crate::hair::*;
99
use rustc::middle::region;
10-
use rustc::mir::interpret::InterpError;
10+
use rustc::mir::interpret::{InterpError::Panic, PanicMessage};
1111
use rustc::mir::*;
1212
use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts};
1313
use syntax_pos::Span;
@@ -101,7 +101,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
101101
block,
102102
Operand::Move(is_min),
103103
false,
104-
InterpError::OverflowNeg,
104+
Panic(PanicMessage::OverflowNeg),
105105
expr_span,
106106
);
107107
}
@@ -401,7 +401,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
401401
let val = result_value.clone().field(val_fld, ty);
402402
let of = result_value.field(of_fld, bool_ty);
403403

404-
let err = InterpError::Overflow(op);
404+
let err = Panic(PanicMessage::Overflow(op));
405405

406406
block = self.assert(block, Operand::Move(of), false, err, span);
407407

@@ -412,9 +412,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
412412
// and 2. there are two possible failure cases, divide-by-zero and overflow.
413413

414414
let (zero_err, overflow_err) = if op == BinOp::Div {
415-
(InterpError::DivisionByZero, InterpError::Overflow(op))
415+
(Panic(PanicMessage::DivisionByZero), Panic(PanicMessage::Overflow(op)))
416416
} else {
417-
(InterpError::RemainderByZero, InterpError::Overflow(op))
417+
(Panic(PanicMessage::RemainderByZero), Panic(PanicMessage::Overflow(op)))
418418
};
419419

420420
// Check for / 0

src/librustc_mir/interpret/intrinsics.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc::ty;
77
use rustc::ty::layout::{LayoutOf, Primitive, Size};
88
use rustc::mir::BinOp;
99
use rustc::mir::interpret::{
10-
InterpResult, InterpError, Scalar,
10+
InterpResult, InterpError, Scalar, PanicMessage,
1111
};
1212

1313
use super::{
@@ -261,7 +261,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
261261
let file = Symbol::intern(self.read_str(file_place)?);
262262
let line = self.read_scalar(line.into())?.to_u32()?;
263263
let col = self.read_scalar(col.into())?.to_u32()?;
264-
return Err(InterpError::Panic { msg, file, line, col }.into());
264+
return Err(InterpError::Panic(PanicMessage::Panic { msg, file, line, col }).into());
265265
} else if Some(def_id) == self.tcx.lang_items().begin_panic_fn() {
266266
assert!(args.len() == 2);
267267
// &'static str, &(&'static str, u32, u32)
@@ -279,7 +279,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
279279
let file = Symbol::intern(self.read_str(file_place)?);
280280
let line = self.read_scalar(line.into())?.to_u32()?;
281281
let col = self.read_scalar(col.into())?.to_u32()?;
282-
return Err(InterpError::Panic { msg, file, line, col }.into());
282+
return Err(InterpError::Panic(PanicMessage::Panic { msg, file, line, col }).into());
283283
} else {
284284
return Ok(false);
285285
}

src/librustc_mir/interpret/operator.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc::mir;
22
use rustc::ty::{self, layout::TyLayout};
33
use syntax::ast::FloatTy;
44
use rustc_apfloat::Float;
5-
use rustc::mir::interpret::{InterpResult, Scalar};
5+
use rustc::mir::interpret::{InterpResult, PanicMessage, Scalar};
66

77
use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy};
88

@@ -173,8 +173,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
173173
return Ok((Scalar::from_bool(op(&l, &r)), false));
174174
}
175175
let op: Option<fn(i128, i128) -> (i128, bool)> = match bin_op {
176-
Div if r == 0 => return err!(DivisionByZero),
177-
Rem if r == 0 => return err!(RemainderByZero),
176+
Div if r == 0 => return err!(Panic(PanicMessage::DivisionByZero)),
177+
Rem if r == 0 => return err!(Panic(PanicMessage::RemainderByZero)),
178178
Div => Some(i128::overflowing_div),
179179
Rem => Some(i128::overflowing_rem),
180180
Add => Some(i128::overflowing_add),
@@ -231,8 +231,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
231231
Add => u128::overflowing_add,
232232
Sub => u128::overflowing_sub,
233233
Mul => u128::overflowing_mul,
234-
Div if r == 0 => return err!(DivisionByZero),
235-
Rem if r == 0 => return err!(RemainderByZero),
234+
Div if r == 0 => return err!(Panic(PanicMessage::DivisionByZero)),
235+
Rem if r == 0 => return err!(Panic(PanicMessage::RemainderByZero)),
236236
Div => u128::overflowing_div,
237237
Rem => u128::overflowing_rem,
238238
_ => bug!(),

0 commit comments

Comments
 (0)