ErroneousReferencedConstant(ref const_val) => {
const_val.hash_stable(hcx, hasher);
}
+ Miri(ref err) => err.hash_stable(hcx, hasher),
}
}
}
predicates
});
+impl<'gcx> HashStable<StableHashingContext<'gcx>>
+for ::mir::interpret::EvalError<'gcx> {
+ fn hash_stable<W: StableHasherResult>(&self,
+ hcx: &mut StableHashingContext<'gcx>,
+ hasher: &mut StableHasher<W>) {
+ use mir::interpret::EvalErrorKind::*;
+
+ mem::discriminant(&self.kind).hash_stable(hcx, hasher);
+
+ match self.kind {
+ DanglingPointerDeref |
+ DoubleFree |
+ InvalidMemoryAccess |
+ InvalidFunctionPointer |
+ InvalidBool |
+ InvalidDiscriminant |
+ InvalidNullPointerUsage |
+ ReadPointerAsBytes |
+ ReadBytesAsPointer |
+ InvalidPointerMath |
+ ReadUndefBytes |
+ DeadLocal |
+ ExecutionTimeLimitReached |
+ StackFrameLimitReached |
+ OutOfTls |
+ TlsOutOfBounds |
+ CalledClosureAsFunction |
+ VtableForArgumentlessMethod |
+ ModifiedConstantMemory |
+ AssumptionNotHeld |
+ InlineAsm |
+ ReallocateNonBasePtr |
+ DeallocateNonBasePtr |
+ HeapAllocZeroBytes |
+ Unreachable |
+ Panic |
+ ReadFromReturnPointer |
+ UnimplementedTraitSelection |
+ TypeckError |
+ DerefFunctionPointer |
+ ExecuteMemory |
+ OverflowingMath => {}
+ MachineError(ref err) => err.hash_stable(hcx, hasher),
+ FunctionPointerTyMismatch(a, b) => {
+ a.hash_stable(hcx, hasher);
+ b.hash_stable(hcx, hasher)
+ },
+ NoMirFor(ref s) => s.hash_stable(hcx, hasher),
+ UnterminatedCString(ptr) => ptr.hash_stable(hcx, hasher),
+ PointerOutOfBounds {
+ ptr,
+ access,
+ allocation_size,
+ } => {
+ ptr.hash_stable(hcx, hasher);
+ access.hash_stable(hcx, hasher);
+ allocation_size.hash_stable(hcx, hasher)
+ },
+ InvalidBoolOp(bop) => bop.hash_stable(hcx, hasher),
+ Unimplemented(ref s) => s.hash_stable(hcx, hasher),
+ ArrayIndexOutOfBounds(sp, a, b) => {
+ sp.hash_stable(hcx, hasher);
+ a.hash_stable(hcx, hasher);
+ b.hash_stable(hcx, hasher)
+ },
+ Math(sp, ref err) => {
+ sp.hash_stable(hcx, hasher);
+ err.hash_stable(hcx, hasher)
+ },
+ Intrinsic(ref s) => s.hash_stable(hcx, hasher),
+ InvalidChar(c) => c.hash_stable(hcx, hasher),
+ OutOfMemory {
+ allocation_size,
+ memory_size,
+ memory_usage,
+ } => {
+ allocation_size.hash_stable(hcx, hasher);
+ memory_size.hash_stable(hcx, hasher);
+ memory_usage.hash_stable(hcx, hasher)
+ },
+ AbiViolation(ref s) => s.hash_stable(hcx, hasher),
+ AlignmentCheckFailed {
+ required,
+ has,
+ } => {
+ required.hash_stable(hcx, hasher);
+ has.hash_stable(hcx, hasher)
+ },
+ MemoryLockViolation {
+ ptr,
+ len,
+ frame,
+ access,
+ ref lock,
+ } => {
+ ptr.hash_stable(hcx, hasher);
+ len.hash_stable(hcx, hasher);
+ frame.hash_stable(hcx, hasher);
+ access.hash_stable(hcx, hasher);
+ lock.hash_stable(hcx, hasher)
+ },
+ MemoryAcquireConflict {
+ ptr,
+ len,
+ kind,
+ ref lock,
+ } => {
+ ptr.hash_stable(hcx, hasher);
+ len.hash_stable(hcx, hasher);
+ kind.hash_stable(hcx, hasher);
+ lock.hash_stable(hcx, hasher)
+ },
+ InvalidMemoryLockRelease {
+ ptr,
+ len,
+ frame,
+ ref lock,
+ } => {
+ ptr.hash_stable(hcx, hasher);
+ len.hash_stable(hcx, hasher);
+ frame.hash_stable(hcx, hasher);
+ lock.hash_stable(hcx, hasher)
+ },
+ DeallocatedLockedMemory {
+ ptr,
+ ref lock,
+ } => {
+ ptr.hash_stable(hcx, hasher);
+ lock.hash_stable(hcx, hasher)
+ },
+ ValidationFailure(ref s) => s.hash_stable(hcx, hasher),
+ TypeNotPrimitive(ty) => ty.hash_stable(hcx, hasher),
+ ReallocatedWrongMemoryKind(ref a, ref b) => {
+ a.hash_stable(hcx, hasher);
+ b.hash_stable(hcx, hasher)
+ },
+ DeallocatedWrongMemoryKind(ref a, ref b) => {
+ a.hash_stable(hcx, hasher);
+ b.hash_stable(hcx, hasher)
+ },
+ IncorrectAllocationInformation(a, b, c, d) => {
+ a.hash_stable(hcx, hasher);
+ b.hash_stable(hcx, hasher);
+ c.hash_stable(hcx, hasher);
+ d.hash_stable(hcx, hasher)
+ },
+ Layout(lay) => lay.hash_stable(hcx, hasher),
+ HeapAllocNonPowerOfTwoAlignment(n) => n.hash_stable(hcx, hasher),
+ PathNotFound(ref v) => v.hash_stable(hcx, hasher),
+ }
+ }
+}
+
+impl_stable_hash_for!(enum mir::interpret::Lock {
+ NoLock,
+ WriteLock(dl),
+ ReadLock(v)
+});
+
+impl_stable_hash_for!(struct mir::interpret::DynamicLifetime {
+ frame,
+ region
+});
+
+impl_stable_hash_for!(enum mir::interpret::AccessKind {
+ Read,
+ Write
+});
+
impl_stable_hash_for!(enum ty::Variance {
Covariant,
Invariant,
TypeckError,
CheckMatchError,
+ Miri(::mir::interpret::EvalError<'tcx>),
+}
+
+impl<'tcx> From<::mir::interpret::EvalError<'tcx>> for ErrKind<'tcx> {
+ fn from(err: ::mir::interpret::EvalError<'tcx>) -> ErrKind<'tcx> {
+ ErrKind::Miri(err)
+ }
}
impl<'tcx> From<ConstMathErr> for ErrKind<'tcx> {
TypeckError => simple!("type-checking failed"),
CheckMatchError => simple!("match-checking failed"),
+ Miri(ref err) => simple!("miri failed: {}", err),
}
}
use syntax::codemap::Span;
use backtrace::Backtrace;
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct EvalError<'tcx> {
pub kind: EvalErrorKind<'tcx>,
pub backtrace: Option<Backtrace>,
}
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub enum EvalErrorKind<'tcx> {
/// This variant is used by machines to signal their own errors that do not
/// match an existing variant
- MachineError(Box<dyn Error>),
+ MachineError(String),
FunctionPointerTyMismatch(FnSig<'tcx>, FnSig<'tcx>),
NoMirFor(String),
UnterminatedCString(MemoryPointer),
fn description(&self) -> &str {
use self::EvalErrorKind::*;
match self.kind {
- MachineError(ref inner) => inner.description(),
+ MachineError(ref inner) => inner,
FunctionPointerTyMismatch(..) =>
"tried to call a function through a function pointer of a different type",
InvalidMemoryAccess =>
"encountered constants with type errors, stopping evaluation",
}
}
-
- fn cause(&self) -> Option<&dyn Error> {
- use self::EvalErrorKind::*;
- match self.kind {
- MachineError(ref inner) => Some(&**inner),
- _ => None,
- }
- }
}
impl<'tcx> fmt::Display for EvalError<'tcx> {
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use rustc_data_structures::accumulate_vec::AccumulateVec;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use mir::interpret;
use std::rc::Rc;
}
}
+impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
+ type Lifted = interpret::EvalError<'tcx>;
+ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
+ use mir::interpret::EvalErrorKind::*;
+ let kind = match self.kind {
+ MachineError(ref err) => MachineError(err.clone()),
+ FunctionPointerTyMismatch(a, b) => FunctionPointerTyMismatch(
+ tcx.lift(&a)?,
+ tcx.lift(&b)?,
+ ),
+ NoMirFor(ref s) => NoMirFor(s.clone()),
+ UnterminatedCString(ptr) => UnterminatedCString(ptr),
+ DanglingPointerDeref => DanglingPointerDeref,
+ DoubleFree => DoubleFree,
+ InvalidMemoryAccess => InvalidMemoryAccess,
+ InvalidFunctionPointer => InvalidFunctionPointer,
+ InvalidBool => InvalidBool,
+ InvalidDiscriminant => InvalidDiscriminant,
+ PointerOutOfBounds {
+ ptr,
+ access,
+ allocation_size,
+ } => PointerOutOfBounds { ptr, access, allocation_size },
+ InvalidNullPointerUsage => InvalidNullPointerUsage,
+ ReadPointerAsBytes => ReadPointerAsBytes,
+ ReadBytesAsPointer => ReadBytesAsPointer,
+ InvalidPointerMath => InvalidPointerMath,
+ ReadUndefBytes => ReadUndefBytes,
+ DeadLocal => DeadLocal,
+ InvalidBoolOp(bop) => InvalidBoolOp(bop),
+ Unimplemented(ref s) => Unimplemented(s.clone()),
+ DerefFunctionPointer => DerefFunctionPointer,
+ ExecuteMemory => ExecuteMemory,
+ ArrayIndexOutOfBounds(sp, a, b) => ArrayIndexOutOfBounds(sp, a, b),
+ Math(sp, ref err) => Math(sp, err.clone()),
+ Intrinsic(ref s) => Intrinsic(s.clone()),
+ OverflowingMath => OverflowingMath,
+ InvalidChar(c) => InvalidChar(c),
+ OutOfMemory {
+ allocation_size,
+ memory_size,
+ memory_usage,
+ } => OutOfMemory { allocation_size, memory_size, memory_usage },
+ ExecutionTimeLimitReached => ExecutionTimeLimitReached,
+ StackFrameLimitReached => StackFrameLimitReached,
+ OutOfTls => OutOfTls,
+ TlsOutOfBounds => TlsOutOfBounds,
+ AbiViolation(ref s) => AbiViolation(s.clone()),
+ AlignmentCheckFailed {
+ required,
+ has,
+ } => AlignmentCheckFailed { required, has },
+ MemoryLockViolation {
+ ptr,
+ len,
+ frame,
+ access,
+ ref lock,
+ } => MemoryLockViolation { ptr, len, frame, access, lock: lock.clone() },
+ MemoryAcquireConflict {
+ ptr,
+ len,
+ kind,
+ ref lock,
+ } => MemoryAcquireConflict { ptr, len, kind, lock: lock.clone() },
+ InvalidMemoryLockRelease {
+ ptr,
+ len,
+ frame,
+ ref lock,
+ } => InvalidMemoryLockRelease { ptr, len, frame, lock: lock.clone() },
+ DeallocatedLockedMemory {
+ ptr,
+ ref lock,
+ } => DeallocatedLockedMemory { ptr, lock: lock.clone() },
+ ValidationFailure(ref s) => ValidationFailure(s.clone()),
+ CalledClosureAsFunction => CalledClosureAsFunction,
+ VtableForArgumentlessMethod => VtableForArgumentlessMethod,
+ ModifiedConstantMemory => ModifiedConstantMemory,
+ AssumptionNotHeld => AssumptionNotHeld,
+ InlineAsm => InlineAsm,
+ TypeNotPrimitive(ty) => TypeNotPrimitive(tcx.lift(&ty)?),
+ ReallocatedWrongMemoryKind(ref a, ref b) => {
+ ReallocatedWrongMemoryKind(a.clone(), b.clone())
+ },
+ DeallocatedWrongMemoryKind(ref a, ref b) => {
+ DeallocatedWrongMemoryKind(a.clone(), b.clone())
+ },
+ ReallocateNonBasePtr => ReallocateNonBasePtr,
+ DeallocateNonBasePtr => DeallocateNonBasePtr,
+ IncorrectAllocationInformation(a, b, c, d) => {
+ IncorrectAllocationInformation(a, b, c, d)
+ },
+ Layout(lay) => Layout(tcx.lift(&lay)?),
+ HeapAllocZeroBytes => HeapAllocZeroBytes,
+ HeapAllocNonPowerOfTwoAlignment(n) => HeapAllocNonPowerOfTwoAlignment(n),
+ Unreachable => Unreachable,
+ Panic => Panic,
+ ReadFromReturnPointer => ReadFromReturnPointer,
+ PathNotFound(ref v) => PathNotFound(v.clone()),
+ UnimplementedTraitSelection => UnimplementedTraitSelection,
+ TypeckError => TypeckError,
+ };
+ Some(interpret::EvalError {
+ kind,
+ backtrace: self.backtrace.clone(),
+ })
+ }
+}
+
impl<'a, 'tcx> Lift<'tcx> for const_val::ErrKind<'a> {
type Lifted = const_val::ErrKind<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
TypeckError => TypeckError,
CheckMatchError => CheckMatchError,
+ Miri(ref e) => return tcx.lift(e).map(Miri),
})
}
}