]> git.lizzy.rs Git - rust.git/commitdiff
Add miri errors to the const eval error enum
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Tue, 16 Jan 2018 08:13:50 +0000 (09:13 +0100)
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Thu, 8 Mar 2018 07:06:07 +0000 (08:06 +0100)
src/librustc/ich/impls_ty.rs
src/librustc/middle/const_val.rs
src/librustc/mir/interpret/error.rs
src/librustc/ty/structural_impls.rs

index 06a60bfb0eba6744c6e680a1147d3fce70dfe47f..4d802491c96edf8eeba9f5ba2873cba698b75ccb 100644 (file)
@@ -470,6 +470,7 @@ fn hash_stable<W: StableHasherResult>(&self,
             ErroneousReferencedConstant(ref const_val) => {
                 const_val.hash_stable(hcx, hasher);
             }
+            Miri(ref err) => err.hash_stable(hcx, hasher),
         }
     }
 }
@@ -483,6 +484,175 @@ fn hash_stable<W: StableHasherResult>(&self,
     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,
index 2309131c57a9f483d62470c23fcd92e61f64bab8..589890947cd5aabe02f7145e191151417e3184da 100644 (file)
@@ -111,6 +111,13 @@ pub enum ErrKind<'tcx> {
 
     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> {
@@ -173,6 +180,7 @@ macro_rules! simple {
 
             TypeckError => simple!("type-checking failed"),
             CheckMatchError => simple!("match-checking failed"),
+            Miri(ref err) => simple!("miri failed: {}", err),
         }
     }
 
index f9ea544156ce3d661fb0ec8e9a0b012d8df76a9c..6386de5952f99905806162195109bf62b7445846 100644 (file)
@@ -12,7 +12,7 @@
 use syntax::codemap::Span;
 use backtrace::Backtrace;
 
-#[derive(Debug)]
+#[derive(Debug, Clone)]
 pub struct EvalError<'tcx> {
     pub kind: EvalErrorKind<'tcx>,
     pub backtrace: Option<Backtrace>,
@@ -31,11 +31,11 @@ fn from(kind: EvalErrorKind<'tcx>) -> Self {
     }
 }
 
-#[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),
@@ -132,7 +132,7 @@ impl<'tcx> Error for EvalError<'tcx> {
     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 =>
@@ -247,14 +247,6 @@ fn description(&self) -> &str {
                 "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> {
index 3e7468d2ccab4545977b1babe5d35d7e81c05dd3..54db2d4f06be5485d4bba95ced1bdf53d516e83d 100644 (file)
@@ -18,6 +18,7 @@
 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;
 
@@ -585,6 +586,116 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
     }
 }
 
+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> {
@@ -614,6 +725,7 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
 
             TypeckError => TypeckError,
             CheckMatchError => CheckMatchError,
+            Miri(ref e) => return tcx.lift(e).map(Miri),
         })
     }
 }