#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
pub enum InvalidProgramInfo<'tcx> {
- /// Resolution can fail if we are in a too generic context
+ /// Resolution can fail if we are in a too generic context.
TooGeneric,
/// Cannot compute this constant because it depends on another one
- /// which already produced an error
+ /// which already produced an error.
ReferencedConstant,
- /// Abort in case type errors are reached
+ /// Abort in case type errors are reached.
TypeckError,
/// An error occurred during layout computation.
Layout(layout::LayoutError<'tcx>),
}
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
-pub enum UnsupportedInfo<'tcx> {
+pub enum UnsupportedOpInfo<'tcx> {
/// Handle cases which for which we do not have a fixed variant.
Unimplemented(String),
PathNotFound(Vec<String>),
}
-impl fmt::Debug for UnsupportedInfo<'tcx> {
+impl fmt::Debug for UnsupportedOpInfo<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- use UnsupportedInfo::*;
+ use UnsupportedOpInfo::*;
match self {
PointerOutOfBounds { ptr, msg, allocation_size } => {
write!(f, "{} failed: pointer must be in-bounds at offset {}, \
UndefinedBehaviour(UndefinedBehaviourInfo),
/// The program did something the interpreter does not support (some of these *might* be UB
/// but the interpreter is not sure).
- Unsupported(UnsupportedInfo<'tcx>),
+ Unsupported(UnsupportedOpInfo<'tcx>),
/// The program was invalid (ill-typed, not sufficiently monomorphized, ...).
InvalidProgram(InvalidProgramInfo<'tcx>),
/// The program exhausted the interpreter's resources (stack/heap too big,
macro_rules! err {
($($tt:tt)*) => {
Err($crate::mir::interpret::InterpError::Unsupported(
- $crate::mir::interpret::UnsupportedInfo::$($tt)*
+ $crate::mir::interpret::UnsupportedOpInfo::$($tt)*
).into())
};
}
pub use self::error::{
InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error,
- FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicInfo, UnsupportedInfo,
+ FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicInfo, UnsupportedOpInfo,
InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviourInfo,
};
msg: CheckInAllocMsg,
) -> InterpResult<'tcx, ()> {
if self.offset > allocation_size {
- err!(PointerOutOfBounds { ptr: self.erase_tag(),msg,allocation_size })
+ err!(PointerOutOfBounds { ptr: self.erase_tag(), msg, allocation_size })
} else {
Ok(())
}
RawConst, ConstValue,
InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpCx, StackPopCleanup,
Allocation, AllocId, MemoryKind,
- snapshot, RefTracking, intern_const_alloc_recursive, UnsupportedInfo::*,
- InvalidProgramInfo::*,
+ snapshot, RefTracking, intern_const_alloc_recursive, UnsupportedOpInfo,
};
/// Number of steps until the detector even starts doing anything.
impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalError {
fn into(self) -> InterpErrorInfo<'tcx> {
- InterpError::Unsupported(MachineError(self.to_string())).into()
+ InterpError::Unsupported(UnsupportedOpInfo::MachineError(self.to_string())).into()
}
}
Ok(Some(match ecx.load_mir(instance.def) {
Ok(body) => body,
Err(err) => {
- if let InterpError::Unsupported(NoMirFor(ref path)) = err.kind {
+ if let InterpError::Unsupported(UnsupportedOpInfo::NoMirFor(ref path)) = err.kind {
return Err(
ConstEvalError::NeedsRfc(format!("calling extern function `{}`", path))
.into(),
// promoting runtime code is only allowed to error if it references broken constants
// any other kind of error will be reported to the user as a deny-by-default lint
_ => if let Some(p) = cid.promoted {
+ use crate::interpret::InvalidProgramInfo::*;
let span = tcx.promoted_mir(def_id)[p].span;
if let InterpError::InvalidProgram(ReferencedConstant) = err.error {
err.report_as_error(
use rustc::mir::interpret::{
Scalar, InterpResult, Pointer, PointerArithmetic, InterpError,
};
-use rustc::mir::{CastKind, interpret::{InvalidProgramInfo::*}};
-
+use rustc::mir::CastKind;
use super::{InterpCx, Machine, PlaceTy, OpTy, Immediate, FnVal};
}
Pointer(PointerCast::ReifyFnPointer) => {
+ use rustc::mir::interpret::InvalidProgramInfo::TooGeneric;
// The src operand does not matter, just its type
match src.layout.ty.sty {
ty::FnDef(def_id, substs) => {
ErrorHandled,
GlobalId, Scalar, Pointer, FrameInfo, AllocId,
InterpResult, InterpError,
- truncate, sign_extend, InvalidProgramInfo::*,
+ truncate, sign_extend, InvalidProgramInfo,
};
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| InterpError::InvalidProgram(Layout(layout)).into())
+ self.tcx
+ .layout_of(self.param_env.and(ty))
+ .map_err(|layout| {
+ InterpError::InvalidProgram(InvalidProgramInfo::Layout(layout)).into()
+ })
}
}
&substs,
)),
None => if substs.needs_subst() {
- err_inval!(TooGeneric).into()
+ err_inval!(TooGeneric)
} else {
Ok(substs)
},
self.param_env,
def_id,
substs,
- ).ok_or_else(|| InterpError::InvalidProgram(TooGeneric).into())
+ ).ok_or_else(|| InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric).into())
}
pub fn load_mir(
// `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 => InterpError::InvalidProgram(ReferencedConstant),
- ErrorHandled::TooGeneric => InterpError::InvalidProgram(TooGeneric),
+ ErrorHandled::Reported =>
+ InterpError::InvalidProgram(InvalidProgramInfo::ReferencedConstant),
+ ErrorHandled::TooGeneric =>
+ InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric),
}
})?;
self.raw_const_to_mplace(val)
use rustc::ty::{Ty, TyCtxt, ParamEnv, self};
use rustc::mir::interpret::{
- InterpResult, ErrorHandled, UnsupportedInfo::*,
+ InterpResult, ErrorHandled, UnsupportedOpInfo,
};
use rustc::hir;
use rustc::hir::def_id::DefId;
if let Err(error) = interned {
// This can happen when e.g. the tag of an enum is not a valid discriminant. We do have
// to read enum discriminants in order to find references in enum variant fields.
- if let InterpError::Unsupported(ValidationFailure(_)) = error.kind {
+ if let InterpError::Unsupported(UnsupportedOpInfo::ValidationFailure(_)) = error.kind {
let err = crate::const_eval::error_to_const_error(&ecx, error);
match err.struct_error(ecx.tcx, "it is undefined behavior to use this value") {
Ok(mut diag) => {
use rustc::ty::layout::{LayoutOf, Primitive, Size};
use rustc::mir::BinOp;
use rustc::mir::interpret::{
- InterpResult, InterpError, Scalar, PanicInfo, UnsupportedInfo::*,
+ InterpResult, InterpError, Scalar, PanicInfo, UnsupportedOpInfo,
};
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(InterpError::Unsupported(TypeNotPrimitive(ty)))?,
+ _ => Err(InterpError::Unsupported(UnsupportedOpInfo::TypeNotPrimitive(ty)))?,
};
let out_val = if intrinsic_name.ends_with("_nonzero") {
if bits == 0 {
use super::{
Allocation, AllocId, InterpResult, InterpError, Scalar, AllocationExtra,
- InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory, UnsupportedInfo::*
+ InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory, UnsupportedOpInfo,
};
/// Whether this kind of memory is allowed to leak
int: u64,
) -> InterpResult<'tcx, Pointer<Self::PointerTag>> {
Err((if int == 0 {
- InterpError::Unsupported(InvalidNullPointerUsage)
+ InterpError::Unsupported(UnsupportedOpInfo::InvalidNullPointerUsage)
} else {
- InterpError::Unsupported(ReadBytesAsPointer)
+ InterpError::Unsupported(UnsupportedOpInfo::ReadBytesAsPointer)
}).into())
}
use super::{
Pointer, AllocId, Allocation, GlobalId, AllocationExtra,
InterpResult, Scalar, InterpError, GlobalAlloc, PointerArithmetic,
- Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, UnsupportedInfo::*,
- InvalidProgramInfo::*
+ Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, InvalidProgramInfo,
};
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
assert!(tcx.is_static(def_id));
match err {
ErrorHandled::Reported =>
- InterpError::InvalidProgram(ReferencedConstant),
+ InterpError::InvalidProgram(
+ InvalidProgramInfo::ReferencedConstant
+ ),
ErrorHandled::TooGeneric =>
- InterpError::InvalidProgram(TooGeneric),
+ InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric),
}
})?;
// Make sure we use the ID of the resolved memory, not the lazy one!
} else {
match self.tcx.alloc_map.lock().get(id) {
Some(GlobalAlloc::Function(instance)) => Ok(FnVal::Instance(instance)),
- _ => Err(InterpError::Unsupported(ExecuteMemory).into()),
+ _ => err!(ExecuteMemory),
}
}
}
GlobalId, AllocId,
ConstValue, Pointer, Scalar,
InterpResult, InterpError,
- sign_extend, truncate, UnsupportedInfo::*,
+ sign_extend, truncate, UnsupportedOpInfo,
};
use super::{
InterpCx, Machine,
) -> InterpResult<'tcx, &str> {
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| InterpError::Unsupported(ValidationFailure(err.to_string())))?;
+ let str = ::std::str::from_utf8(bytes).map_err(|err| {
+ InterpError::Unsupported(UnsupportedOpInfo::ValidationFailure(err.to_string()))
+ })?;
Ok(str)
}
let raw_discr = discr_val.to_scalar_or_undef();
trace!("discr value: {:?}", raw_discr);
// post-process
+ use rustc::mir::interpret::UnsupportedOpInfo::InvalidDiscriminant;
Ok(match *discr_kind {
layout::DiscriminantKind::Tag => {
let bits_discr = match raw_discr.to_bits(discr_val.layout.size) {
use rustc::mir::interpret::{
AllocId, Pointer, Scalar,
Relocations, Allocation, UndefMask,
- InterpResult, InterpError, ResourceExhaustionInfo::*,
+ InterpResult, InterpError, ResourceExhaustionInfo,
};
use rustc::ty::{self, TyCtxt};
}
// Second cycle
- Err(InterpError::ResourceExhaustion(InfiniteLoop).into())
+ Err(InterpError::ResourceExhaustion(ResourceExhaustionInfo::InfiniteLoop).into())
}
}
use super::{
InterpResult, PointerArithmetic, InterpError, Scalar,
InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal,
- UnsupportedInfo::*,
+ UnsupportedOpInfo,
};
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
return Ok(());
}
let caller_arg = caller_arg.next()
- .ok_or_else(|| InterpError::Unsupported(FunctionArgCountMismatch))?;
+ .ok_or_else(|| InterpError::Unsupported(UnsupportedOpInfo::FunctionArgCountMismatch))?;
if rust_abi {
debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out");
}
use super::{
GlobalAlloc, InterpResult, InterpError,
- OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, UnsupportedInfo::*,
+ OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, UnsupportedOpInfo,
};
macro_rules! validation_failure {
match self.walk_value(op) {
Ok(()) => Ok(()),
Err(err) => match err.kind {
- InterpError::Unsupported(InvalidDiscriminant(val)) =>
+ InterpError::Unsupported(UnsupportedOpInfo::InvalidDiscriminant(val)) =>
validation_failure!(
val, self.path, "a valid enum discriminant"
),
- InterpError::Unsupported(ReadPointerAsBytes) =>
+ InterpError::Unsupported(UnsupportedOpInfo::ReadPointerAsBytes) =>
validation_failure!(
"a pointer", self.path, "plain (non-pointer) bytes"
),
"{:?} did not pass access check for size {:?}, align {:?}",
ptr, size, align
);
+ use super::UnsupportedOpInfo::*;
match err.kind {
InterpError::Unsupported(InvalidNullPointerUsage) =>
return validation_failure!("NULL reference", self.path),
Err(err) => {
// For some errors we might be able to provide extra information
match err.kind {
- InterpError::Unsupported(ReadUndefBytes(offset)) => {
+ InterpError::Unsupported(UnsupportedOpInfo::ReadUndefBytes(offset)) => {
// Some byte was undefined, determine which
// element that byte belongs to so we can
// provide an index.
Err(error) => {
let diagnostic = error_to_const_error(&self.ecx, error);
use rustc::mir::interpret::InterpError::*;
- use rustc::mir::interpret::UnsupportedInfo::*;
+ use rustc::mir::interpret::UnsupportedOpInfo::*;
match diagnostic.error {
- Exit(_) => {},
+ Exit(_) => bug!("the CTFE program cannot exit"),
| Unsupported(OutOfTls)
| Unsupported(TlsOutOfBounds)