validate TyClosure, TyTuple, TyNever
This commit is contained in:
parent
dac51f41ad
commit
1f9153fac3
3 changed files with 26 additions and 2 deletions
|
|
@ -57,6 +57,7 @@ pub enum EvalError<'tcx> {
|
|||
access: AccessKind,
|
||||
lock: LockInfo,
|
||||
},
|
||||
ValidationFailure(String),
|
||||
InvalidMemoryLockRelease {
|
||||
ptr: MemoryPointer,
|
||||
len: u64,
|
||||
|
|
@ -110,6 +111,8 @@ impl<'tcx> Error for EvalError<'tcx> {
|
|||
"invalid use of NULL pointer",
|
||||
MemoryLockViolation { .. } =>
|
||||
"memory access conflicts with lock",
|
||||
ValidationFailure(..) =>
|
||||
"type validation failed",
|
||||
DeallocatedLockedMemory =>
|
||||
"deallocated memory while a lock was held",
|
||||
InvalidMemoryLockRelease { .. } =>
|
||||
|
|
@ -221,6 +224,9 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
|
|||
write!(f, "tried to release memory write lock at {:?}, size {}, which was not acquired by this function",
|
||||
ptr, len)
|
||||
}
|
||||
ValidationFailure(ref err) => {
|
||||
write!(f, "type validation failed: {}", err)
|
||||
}
|
||||
NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
|
||||
FunctionPointerTyMismatch(sig, got) =>
|
||||
write!(f, "tried to call a function with sig {} through a function pointer of type {}", sig, got),
|
||||
|
|
|
|||
|
|
@ -539,6 +539,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
// TODO: Check if these are valid bool/float/UTF-8, respectively (and in particular, not undef).
|
||||
Ok(())
|
||||
}
|
||||
TyNever => {
|
||||
Err(EvalError::ValidationFailure(format!("The empty type is never valid.")))
|
||||
}
|
||||
TyRef(region, ty::TypeAndMut { ty: pointee_ty, mutbl }) => {
|
||||
let val = self.read_lvalue(lvalue)?;
|
||||
// Sharing restricts our context
|
||||
|
|
@ -617,6 +620,21 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
TyTuple(ref types, _) => {
|
||||
for (idx, field_ty) in types.iter().enumerate() {
|
||||
let field_lvalue = self.lvalue_field(lvalue, idx, ty, field_ty)?;
|
||||
self.validate(field_lvalue, field_ty, vctx)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
TyClosure(def_id, ref closure_substs) => {
|
||||
for (idx, field_ty) in closure_substs.upvar_tys(def_id, self.tcx).enumerate() {
|
||||
let field_lvalue = self.lvalue_field(lvalue, idx, ty, field_ty)?;
|
||||
self.validate(field_lvalue, field_ty, vctx)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
TyParam(_) | TyInfer(_) => bug!("I got an incomplete type for validation"),
|
||||
_ => unimplemented!("Unimplemented type encountered when checking validity.")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,13 +132,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Validity checks.
|
||||
Validate(ref op, ref lvalues) => {
|
||||
Validate(op, ref lvalues) => {
|
||||
for operand in lvalues {
|
||||
// We need to monomorphize ty *without* erasing lifetimes
|
||||
let ty = operand.ty.subst(self.tcx, self.substs());
|
||||
// TODO: do we have to self.tcx.normalize_associated_type(&{ty}) ? That however seems to erase lifetimes.
|
||||
let lvalue = self.eval_lvalue(&operand.lval)?;
|
||||
self.validate(lvalue, ty, ValidationCtx::new(*op))?;
|
||||
self.validate(lvalue, ty, ValidationCtx::new(op))?;
|
||||
}
|
||||
}
|
||||
EndRegion(ce) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue