#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct ConstEvalErr<'tcx> {
pub span: Span,
- pub error: crate::mir::interpret::EvalErrorKind<'tcx, u64>,
+ pub error: crate::mir::interpret::InterpError<'tcx, u64>,
pub stacktrace: Vec<FrameInfo<'tcx>>,
}
lint_root: Option<hir::HirId>,
) -> Result<DiagnosticBuilder<'tcx>, ErrorHandled> {
match self.error {
- EvalErrorKind::Layout(LayoutError::Unknown(_)) |
- EvalErrorKind::TooGeneric => return Err(ErrorHandled::TooGeneric),
- EvalErrorKind::Layout(LayoutError::SizeOverflow(_)) |
- EvalErrorKind::TypeckError => return Err(ErrorHandled::Reported),
+ InterpError::Layout(LayoutError::Unknown(_)) |
+ InterpError::TooGeneric => return Err(ErrorHandled::TooGeneric),
+ InterpError::Layout(LayoutError::SizeOverflow(_)) |
+ InterpError::TypeckError => return Err(ErrorHandled::Reported),
_ => {},
}
trace!("reporting const eval failure at {:?}", self.span);
#[derive(Debug, Clone)]
pub struct EvalError<'tcx> {
- pub kind: EvalErrorKind<'tcx, u64>,
+ pub kind: InterpError<'tcx, u64>,
pub backtrace: Option<Box<Backtrace>>,
}
eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
}
-impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
- fn from(kind: EvalErrorKind<'tcx, u64>) -> Self {
+impl<'tcx> From<InterpError<'tcx, u64>> for EvalError<'tcx> {
+ fn from(kind: InterpError<'tcx, u64>) -> Self {
let backtrace = match env::var("RUST_CTFE_BACKTRACE") {
// matching RUST_BACKTRACE, we treat "0" the same as "not present".
Ok(ref val) if val != "0" => {
}
}
-pub type AssertMessage<'tcx> = EvalErrorKind<'tcx, mir::Operand<'tcx>>;
+pub type AssertMessage<'tcx> = InterpError<'tcx, mir::Operand<'tcx>>;
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
-pub enum EvalErrorKind<'tcx, O> {
+pub enum InterpError<'tcx, O> {
/// This variant is used by machines to signal their own errors that do not
/// match an existing variant.
MachineError(String),
pub type EvalResult<'tcx, T = ()> = Result<T, EvalError<'tcx>>;
-impl<'tcx, O> EvalErrorKind<'tcx, O> {
+impl<'tcx, O> InterpError<'tcx, O> {
pub fn description(&self) -> &str {
- use self::EvalErrorKind::*;
+ use self::InterpError::*;
match *self {
MachineError(ref inner) => inner,
FunctionAbiMismatch(..) | FunctionArgMismatch(..) | FunctionRetMismatch(..)
}
}
-impl<'tcx> fmt::Display for EvalErrorKind<'tcx, u64> {
+impl<'tcx> fmt::Display for InterpError<'tcx, u64> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
-impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> {
+impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- use self::EvalErrorKind::*;
+ use self::InterpError::*;
match *self {
PointerOutOfBounds { ptr, check, allocation_size } => {
write!(f, "Pointer must be in-bounds{} at offset {}, but is outside bounds of \
#[macro_export]
macro_rules! err {
- ($($tt:tt)*) => { Err($crate::mir::interpret::EvalErrorKind::$($tt)*.into()) };
+ ($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::$($tt)*.into()) };
}
mod error;
mod pointer;
pub use self::error::{
- EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error,
+ EvalError, EvalResult, InterpError, AssertMessage, ConstEvalErr, struct_error,
FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled,
};
use crate::hir::def::{CtorKind, Namespace};
use crate::hir::def_id::DefId;
use crate::hir::{self, HirId, InlineAsm};
-use crate::mir::interpret::{ConstValue, EvalErrorKind, Scalar};
+use crate::mir::interpret::{ConstValue, InterpError, Scalar};
use crate::mir::visit::MirVisitable;
use rustc_apfloat::ieee::{Double, Single};
use rustc_apfloat::Float;
target,
cleanup,
} => {
- let msg = if let EvalErrorKind::BoundsCheck { ref len, ref index } = *msg {
- EvalErrorKind::BoundsCheck {
+ let msg = if let InterpError::BoundsCheck { ref len, ref index } = *msg {
+ InterpError::BoundsCheck {
len: len.fold_with(folder),
index: index.fold_with(folder),
}
ref cond, ref msg, ..
} => {
if cond.visit_with(visitor) {
- if let EvalErrorKind::BoundsCheck { ref len, ref index } = *msg {
+ if let InterpError::BoundsCheck { ref len, ref index } = *msg {
len.visit_with(visitor) || index.visit_with(visitor)
} else {
false
fn super_assert_message(&mut self,
msg: & $($mutability)? AssertMessage<'tcx>,
location: Location) {
- use crate::mir::interpret::EvalErrorKind::*;
+ use crate::mir::interpret::InterpError::*;
if let BoundsCheck { len, index } = msg {
self.visit_operand(len, location);
self.visit_operand(index, location);
use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
use rustc::mir::{self, Place, PlaceBase, Static, StaticKind};
-use rustc::mir::interpret::EvalErrorKind;
+use rustc::mir::interpret::InterpError;
use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode};
use rustc_target::spec::abi::Abi;
use rustc_mir::monomorphize;
// checked operation, just a comparison with the minimum
// value, so we have to check for the assert message.
if !bx.check_overflow() {
- if let mir::interpret::EvalErrorKind::OverflowNeg = *msg {
+ if let mir::interpret::InterpError::OverflowNeg = *msg {
const_cond = Some(expected);
}
}
// Put together the arguments to the panic entry point.
let (lang_item, args) = match *msg {
- EvalErrorKind::BoundsCheck { ref len, ref index } => {
+ InterpError::BoundsCheck { ref len, ref index } => {
let len = self.codegen_operand(&mut bx, len).immediate();
let index = self.codegen_operand(&mut bx, index).immediate();
cleanup: _,
} => {
self.consume_operand(ContextKind::Assert.new(loc), (cond, span), flow_state);
- use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
+ use rustc::mir::interpret::InterpError::BoundsCheck;
if let BoundsCheck { ref len, ref index } = *msg {
self.consume_operand(ContextKind::Assert.new(loc), (len, span), flow_state);
self.consume_operand(ContextKind::Assert.new(loc), (index, span), flow_state);
cleanup: _,
} => {
self.consume_operand(ContextKind::Assert.new(location), cond);
- use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
+ use rustc::mir::interpret::InterpError::BoundsCheck;
if let BoundsCheck { ref len, ref index } = *msg {
self.consume_operand(ContextKind::Assert.new(location), len);
self.consume_operand(ContextKind::Assert.new(location), index);
use rustc::infer::outlives::env::RegionBoundPairs;
use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
use rustc::infer::type_variable::TypeVariableOrigin;
-use rustc::mir::interpret::{EvalErrorKind::BoundsCheck, ConstValue};
+use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue};
use rustc::mir::tcx::PlaceTy;
use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
use rustc::mir::*;
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
use crate::build::{BlockAnd, BlockAndExtension, Builder};
use crate::hair::*;
-use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
+use rustc::mir::interpret::InterpError::BoundsCheck;
use rustc::mir::*;
use rustc::ty::{CanonicalUserTypeAnnotation, Variance};
use crate::build::{BlockAnd, BlockAndExtension, Builder};
use crate::hair::*;
use rustc::middle::region;
-use rustc::mir::interpret::EvalErrorKind;
+use rustc::mir::interpret::InterpError;
use rustc::mir::*;
use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts};
use syntax_pos::Span;
block,
Operand::Move(is_min),
false,
- EvalErrorKind::OverflowNeg,
+ InterpError::OverflowNeg,
expr_span,
);
}
let val = result_value.clone().field(val_fld, ty);
let of = result_value.field(of_fld, bool_ty);
- let err = EvalErrorKind::Overflow(op);
+ let err = InterpError::Overflow(op);
block = self.assert(block, Operand::Move(of), false, err, span);
// and 2. there are two possible failure cases, divide-by-zero and overflow.
let (zero_err, overflow_err) = if op == BinOp::Div {
- (EvalErrorKind::DivisionByZero, EvalErrorKind::Overflow(op))
+ (InterpError::DivisionByZero, InterpError::Overflow(op))
} else {
- (EvalErrorKind::RemainderByZero, EvalErrorKind::Overflow(op))
+ (InterpError::RemainderByZero, InterpError::Overflow(op))
};
// Check for / 0
use crate::interpret::{self,
PlaceTy, MPlaceTy, MemPlace, OpTy, ImmTy, Immediate, Scalar, Pointer,
RawConst, ConstValue,
- EvalResult, EvalError, EvalErrorKind, GlobalId, InterpretCx, StackPopCleanup,
+ EvalResult, EvalError, InterpError, GlobalId, InterpretCx, StackPopCleanup,
Allocation, AllocId, MemoryKind,
snapshot, RefTracking,
};
impl<'tcx> Into<EvalError<'tcx>> for ConstEvalError {
fn into(self) -> EvalError<'tcx> {
- EvalErrorKind::MachineError(self.to_string()).into()
+ InterpError::MachineError(self.to_string()).into()
}
}
Ok(Some(match ecx.load_mir(instance.def) {
Ok(mir) => mir,
Err(err) => {
- if let EvalErrorKind::NoMirFor(ref path) = err.kind {
+ if let InterpError::NoMirFor(ref path) = err.kind {
return Err(
ConstEvalError::NeedsRfc(format!("calling extern function `{}`", path))
.into(),
// any other kind of error will be reported to the user as a deny-by-default lint
_ => if let Some(p) = cid.promoted {
let span = tcx.optimized_mir(def_id).promoted[p].span;
- if let EvalErrorKind::ReferencedConstant = err.error {
+ if let InterpError::ReferencedConstant = err.error {
err.report_as_error(
tcx.at(span),
"evaluation of constant expression failed",
use rustc_apfloat::ieee::{Single, Double};
use rustc::mir::interpret::{
- Scalar, EvalResult, Pointer, PointerArithmetic, EvalErrorKind, truncate
+ Scalar, EvalResult, Pointer, PointerArithmetic, InterpError, truncate
};
use rustc::mir::CastKind;
use rustc_apfloat::Float;
self.param_env,
def_id,
substs,
- ).ok_or_else(|| EvalErrorKind::TooGeneric.into());
+ ).ok_or_else(|| InterpError::TooGeneric.into());
let fn_ptr = self.memory.create_fn_alloc(instance?).with_default_tag();
self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?;
}
use rustc::mir::interpret::{
ErrorHandled,
GlobalId, Scalar, FrameInfo, AllocId,
- EvalResult, EvalErrorKind,
+ EvalResult, InterpError,
truncate, sign_extend,
};
use rustc_data_structures::fx::FxHashMap;
#[inline]
fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
self.tcx.layout_of(self.param_env.and(ty))
- .map_err(|layout| EvalErrorKind::Layout(layout).into())
+ .map_err(|layout| InterpError::Layout(layout).into())
}
}
self.param_env,
def_id,
substs,
- ).ok_or_else(|| EvalErrorKind::TooGeneric.into())
+ ).ok_or_else(|| InterpError::TooGeneric.into())
}
pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
// `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles.
let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| {
match err {
- ErrorHandled::Reported => EvalErrorKind::ReferencedConstant,
- ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric,
+ ErrorHandled::Reported => InterpError::ReferencedConstant,
+ ErrorHandled::TooGeneric => InterpError::TooGeneric,
}
})?;
self.raw_const_to_mplace(val)
match self.stack[frame].locals[local].access() {
Err(err) => {
- if let EvalErrorKind::DeadLocal = err.kind {
+ if let InterpError::DeadLocal = err.kind {
write!(msg, " is dead").unwrap();
} else {
panic!("Failed to access local: {:?}", err);
use rustc::ty::layout::{LayoutOf, Primitive, Size};
use rustc::mir::BinOp;
use rustc::mir::interpret::{
- EvalResult, EvalErrorKind, Scalar,
+ EvalResult, InterpError, Scalar,
};
use super::{
let bits = self.read_scalar(args[0])?.to_bits(layout_of.size)?;
let kind = match layout_of.abi {
ty::layout::Abi::Scalar(ref scalar) => scalar.value,
- _ => Err(::rustc::mir::interpret::EvalErrorKind::TypeNotPrimitive(ty))?,
+ _ => Err(::rustc::mir::interpret::InterpError::TypeNotPrimitive(ty))?,
};
let out_val = if intrinsic_name.ends_with("_nonzero") {
if bits == 0 {
let file = Symbol::intern(self.read_str(file_place)?);
let line = self.read_scalar(line.into())?.to_u32()?;
let col = self.read_scalar(col.into())?.to_u32()?;
- return Err(EvalErrorKind::Panic { msg, file, line, col }.into());
+ return Err(InterpError::Panic { msg, file, line, col }.into());
} else if Some(def_id) == self.tcx.lang_items().begin_panic_fn() {
assert!(args.len() == 2);
// &'static str, &(&'static str, u32, u32)
let file = Symbol::intern(self.read_str(file_place)?);
let line = self.read_scalar(line.into())?.to_u32()?;
let col = self.read_scalar(col.into())?.to_u32()?;
- return Err(EvalErrorKind::Panic { msg, file, line, col }.into());
+ return Err(InterpError::Panic { msg, file, line, col }.into());
} else {
return Ok(false);
}
use super::{
Pointer, AllocId, Allocation, GlobalId, AllocationExtra,
- EvalResult, Scalar, EvalErrorKind, AllocKind, PointerArithmetic,
+ EvalResult, Scalar, InterpError, AllocKind, PointerArithmetic,
Machine, AllocMap, MayLeak, ErrorHandled, InboundsCheck,
};
// no need to report anything, the const_eval call takes care of that for statics
assert!(tcx.is_static(def_id).is_some());
match err {
- ErrorHandled::Reported => EvalErrorKind::ReferencedConstant.into(),
- ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric.into(),
+ ErrorHandled::Reported => InterpError::ReferencedConstant.into(),
+ ErrorHandled::TooGeneric => InterpError::TooGeneric.into(),
}
}).map(|raw_const| {
let allocation = tcx.alloc_map.lock().unwrap_memory(raw_const.alloc_id);
trace!("reading fn ptr: {}", ptr.alloc_id);
match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
Some(AllocKind::Function(instance)) => Ok(instance),
- _ => Err(EvalErrorKind::ExecuteMemory.into()),
+ _ => Err(InterpError::ExecuteMemory.into()),
}
}
use rustc::mir::interpret::{
GlobalId, AllocId, InboundsCheck,
ConstValue, Pointer, Scalar,
- EvalResult, EvalErrorKind,
+ EvalResult, InterpError,
sign_extend, truncate,
};
use super::{
let len = mplace.len(self)?;
let bytes = self.memory.read_bytes(mplace.ptr, Size::from_bytes(len as u64))?;
let str = ::std::str::from_utf8(bytes)
- .map_err(|err| EvalErrorKind::ValidationFailure(err.to_string()))?;
+ .map_err(|err| InterpError::ValidationFailure(err.to_string()))?;
Ok(str)
}
.expect("tagged layout for non adt")
.discriminants(self.tcx.tcx)
.find(|(_, var)| var.val == real_discr)
- .ok_or_else(|| EvalErrorKind::InvalidDiscriminant(raw_discr.erase_tag()))?;
+ .ok_or_else(|| InterpError::InvalidDiscriminant(raw_discr.erase_tag()))?;
(real_discr, index.0)
},
layout::DiscriminantKind::Niche {
use rustc::mir::interpret::{
AllocId, Pointer, Scalar,
Relocations, Allocation, UndefMask,
- EvalResult, EvalErrorKind,
+ EvalResult, InterpError,
};
use rustc::ty::{self, TyCtxt};
}
// Second cycle
- Err(EvalErrorKind::InfiniteLoop.into())
+ Err(InterpError::InfiniteLoop.into())
}
}
use syntax::source_map::Span;
use rustc_target::spec::abi::Abi;
-use rustc::mir::interpret::{EvalResult, PointerArithmetic, EvalErrorKind, Scalar};
+use rustc::mir::interpret::{EvalResult, PointerArithmetic, InterpError, Scalar};
use super::{
InterpretCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup
};
self.goto_block(Some(target))?;
} else {
// Compute error message
- use rustc::mir::interpret::EvalErrorKind::*;
+ use rustc::mir::interpret::InterpError::*;
return match *msg {
BoundsCheck { ref len, ref index } => {
let len = self.read_immediate(self.eval_operand(len, None)?)
return Ok(());
}
let caller_arg = caller_arg.next()
- .ok_or_else(|| EvalErrorKind::FunctionArgCountMismatch)?;
+ .ok_or_else(|| InterpError::FunctionArgCountMismatch)?;
if rust_abi {
debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out");
}
use rustc::ty;
use rustc_data_structures::fx::FxHashSet;
use rustc::mir::interpret::{
- Scalar, AllocKind, EvalResult, EvalErrorKind,
+ Scalar, AllocKind, EvalResult, InterpError,
};
use super::{
match self.walk_value(op) {
Ok(()) => Ok(()),
Err(err) => match err.kind {
- EvalErrorKind::InvalidDiscriminant(val) =>
+ InterpError::InvalidDiscriminant(val) =>
validation_failure!(
val, self.path, "a valid enum discriminant"
),
- EvalErrorKind::ReadPointerAsBytes =>
+ InterpError::ReadPointerAsBytes =>
validation_failure!(
"a pointer", self.path, "plain (non-pointer) bytes"
),
Err(err) => {
error!("{:?} is not aligned to {:?}", ptr, align);
match err.kind {
- EvalErrorKind::InvalidNullPointerUsage =>
+ InterpError::InvalidNullPointerUsage =>
return validation_failure!("NULL reference", self.path),
- EvalErrorKind::AlignmentCheckFailed { required, has } =>
+ InterpError::AlignmentCheckFailed { required, has } =>
return validation_failure!(format!("unaligned reference \
(required {} byte alignment but found {})",
required.bytes(), has.bytes()), self.path),
Err(err) => {
// For some errors we might be able to provide extra information
match err.kind {
- EvalErrorKind::ReadUndefBytes(offset) => {
+ InterpError::ReadUndefBytes(offset) => {
// Some byte was undefined, determine which
// element that byte belongs to so we can
// provide an index.
use rustc::mir::{NullOp, UnOp, StatementKind, Statement, BasicBlock, LocalKind, Static, StaticKind};
use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem};
use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext};
-use rustc::mir::interpret::{EvalErrorKind, Scalar, GlobalId, EvalResult};
+use rustc::mir::interpret::{InterpError, Scalar, GlobalId, EvalResult};
use rustc::ty::{TyCtxt, self, Instance};
use syntax::source_map::{Span, DUMMY_SP};
use rustc::ty::subst::InternalSubsts;
Ok(val) => Some(val),
Err(error) => {
let diagnostic = error_to_const_error(&self.ecx, error);
- use rustc::mir::interpret::EvalErrorKind::*;
+ use rustc::mir::interpret::InterpError::*;
match diagnostic.error {
// don't report these, they make no sense in a const prop context
| MachineError(_)
)
} else {
if overflow {
- let err = EvalErrorKind::Overflow(op).into();
+ let err = InterpError::Overflow(op).into();
let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
return None;
}
.hir()
.as_local_hir_id(self.source.def_id())
.expect("some part of a failing const eval must be local");
- use rustc::mir::interpret::EvalErrorKind::*;
+ use rustc::mir::interpret::InterpError::*;
let msg = match msg {
Overflow(_) |
OverflowNeg |
let mut cases = create_cases(mir, &transform, |point| Some(point.resume));
- use rustc::mir::interpret::EvalErrorKind::{
+ use rustc::mir::interpret::InterpError::{
GeneratorResumedAfterPanic,
GeneratorResumedAfterReturn,
};