we need to normalize associated types also deep in the hierarchy (89)
This commit is contained in:
parent
769a2b5c81
commit
3f8a497bf0
3 changed files with 16 additions and 15 deletions
|
|
@ -7,10 +7,9 @@ use rustc::hir;
|
|||
use rustc::mir::visit::{Visitor, LvalueContext};
|
||||
use rustc::mir;
|
||||
use rustc::traits::Reveal;
|
||||
use rustc::ty::{self, TypeFoldable};
|
||||
use rustc::ty;
|
||||
use rustc::ty::layout::Layout;
|
||||
use rustc::ty::subst::{Subst, Substs};
|
||||
use rustc::infer::TransNormalize;
|
||||
|
||||
use error::{EvalResult, EvalError};
|
||||
use eval_context::{EvalContext, StackPopCleanup};
|
||||
|
|
@ -137,16 +136,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
Validate(op, ref lvalues) => {
|
||||
for operand in lvalues {
|
||||
// We need to monomorphize ty *without* erasing lifetimes
|
||||
let mut ty = operand.ty.subst(self.tcx, self.substs());
|
||||
// This is essentially a copy of normalize_associated_type, but without erasure
|
||||
if ty.has_projection_types() {
|
||||
let param_env = ty::ParamEnv::empty(Reveal::All);
|
||||
ty = self.tcx.infer_ctxt().enter(move |infcx| {
|
||||
ty.trans_normalize(&infcx, param_env)
|
||||
})
|
||||
}
|
||||
|
||||
// Now we can do validation at this type
|
||||
let ty = operand.ty.subst(self.tcx, self.substs());
|
||||
let lvalue = self.eval_lvalue(&operand.lval)?;
|
||||
self.validate(lvalue, ty, ValidationCtx::new(op))?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -467,7 +467,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
pub fn read_discriminant_value(&self, adt_ptr: MemoryPointer, adt_ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
|
||||
use rustc::ty::layout::Layout::*;
|
||||
let adt_layout = self.type_layout(adt_ty)?;
|
||||
trace!("read_discriminant_value {:#?}", adt_layout);
|
||||
//trace!("read_discriminant_value {:#?}", adt_layout);
|
||||
|
||||
let discr_val = match *adt_layout {
|
||||
General { discr, .. } | CEnum { discr, signed: false, .. } => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
use rustc::hir::Mutability;
|
||||
use rustc::mir::{self, ValidationOp};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::{self, Ty, TypeFoldable};
|
||||
use rustc::traits::Reveal;
|
||||
use rustc::infer::TransNormalize;
|
||||
use rustc::middle::region::CodeExtent;
|
||||
|
||||
use error::{EvalError, EvalResult};
|
||||
|
|
@ -55,12 +57,21 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
/// Validate the lvalue at the given type. If `release` is true, just do a release of all write locks
|
||||
pub(super) fn validate(&mut self, lvalue: Lvalue<'tcx>, ty: Ty<'tcx>, mut vctx: ValidationCtx) -> EvalResult<'tcx>
|
||||
pub(super) fn validate(&mut self, lvalue: Lvalue<'tcx>, mut ty: Ty<'tcx>, mut vctx: ValidationCtx) -> EvalResult<'tcx>
|
||||
{
|
||||
use rustc::ty::TypeVariants::*;
|
||||
use rustc::ty::RegionKind::*;
|
||||
use rustc::ty::AdtKind;
|
||||
use self::Mutability::*;
|
||||
|
||||
// This is essentially a copy of normalize_associated_type, but without erasure
|
||||
if ty.has_projection_types() {
|
||||
let param_env = ty::ParamEnv::empty(Reveal::All);
|
||||
ty = self.tcx.infer_ctxt().enter(move |infcx| {
|
||||
ty.trans_normalize(&infcx, param_env)
|
||||
})
|
||||
}
|
||||
let ty = ty; // no more mutation
|
||||
trace!("Validating {:?} at type {}, context {:?}", lvalue, ty, vctx);
|
||||
|
||||
// Decide whether this type *owns* the memory it covers (like integers), or whether it
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue