mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-12 16:45:37 +00:00
Add miri errors to the const eval error enum
This commit is contained in:
parent
38b5ddd39b
commit
c0574c054c
@ -470,6 +470,7 @@ for ::middle::const_val::ErrKind<'gcx> {
|
||||
ErroneousReferencedConstant(ref const_val) => {
|
||||
const_val.hash_stable(hcx, hasher);
|
||||
}
|
||||
Miri(ref err) => err.hash_stable(hcx, hasher),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -483,6 +484,175 @@ impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
|
||||
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,
|
||||
|
@ -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 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||
|
||||
TypeckError => simple!("type-checking failed"),
|
||||
CheckMatchError => simple!("match-checking failed"),
|
||||
Miri(ref err) => simple!("miri failed: {}", err),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ use rustc_const_math::ConstMathErr;
|
||||
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 @@ impl<'tcx> From<EvalErrorKind<'tcx>> for EvalError<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[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 @@ impl<'tcx> Error for EvalError<'tcx> {
|
||||
"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> {
|
||||
|
@ -18,6 +18,7 @@ use ty::{self, Lift, Ty, TyCtxt};
|
||||
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 @@ impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ impl<'a, 'tcx> Lift<'tcx> for const_val::ErrKind<'a> {
|
||||
|
||||
TypeckError => TypeckError,
|
||||
CheckMatchError => CheckMatchError,
|
||||
Miri(ref e) => return tcx.lift(e).map(Miri),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user