add user_ty.projs support to AscribeUserType.

This commit is contained in:
Felix S. Klock II 2018-10-26 14:00:07 +02:00
parent 82ab668a55
commit 639a3ffadc
3 changed files with 29 additions and 10 deletions

View File

@ -11,6 +11,7 @@
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse};
use traits::query::Fallible;
use hir::def_id::DefId;
use mir::ProjectionKind;
use ty::{self, ParamEnvAnd, Ty, TyCtxt};
use ty::subst::UserSubsts;
@ -20,6 +21,7 @@ pub struct AscribeUserType<'tcx> {
pub variance: ty::Variance,
pub def_id: DefId,
pub user_substs: UserSubsts<'tcx>,
pub projs: &'tcx ty::List<ProjectionKind<'tcx>>,
}
impl<'tcx> AscribeUserType<'tcx> {
@ -28,8 +30,9 @@ impl<'tcx> AscribeUserType<'tcx> {
variance: ty::Variance,
def_id: DefId,
user_substs: UserSubsts<'tcx>,
projs: &'tcx ty::List<ProjectionKind<'tcx>>,
) -> Self {
AscribeUserType { mir_ty, variance, def_id, user_substs }
AscribeUserType { mir_ty, variance, def_id, user_substs, projs }
}
}
@ -59,19 +62,19 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for AscribeUserType<'tcx>
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for AscribeUserType<'tcx> {
mir_ty, variance, def_id, user_substs
mir_ty, variance, def_id, user_substs, projs
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for AscribeUserType<'a> {
type Lifted = AscribeUserType<'tcx>;
mir_ty, variance, def_id, user_substs
mir_ty, variance, def_id, user_substs, projs
}
}
impl_stable_hash_for! {
struct AscribeUserType<'tcx> {
mir_ty, variance, def_id, user_substs
mir_ty, variance, def_id, user_substs, projs
}
}

View File

@ -1013,12 +1013,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
) = self.infcx
.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_substs);
// FIXME: add user_ty.projs support to `AscribeUserType`.
let projs = self.infcx.tcx.intern_projs(&user_ty.projs);
self.fully_perform_op(
locations,
category,
self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
a, v, def_id, user_substs,
a, v, def_id, user_substs, projs,
)),
)?;
}

View File

@ -12,6 +12,8 @@ use rustc::infer::at::ToTrace;
use rustc::infer::canonical::{Canonical, QueryResponse};
use rustc::infer::InferCtxt;
use rustc::hir::def_id::DefId;
use rustc::mir::ProjectionKind;
use rustc::mir::tcx::PlaceTy;
use rustc::traits::query::type_op::ascribe_user_type::AscribeUserType;
use rustc::traits::query::type_op::eq::Eq;
use rustc::traits::query::type_op::normalize::Normalize;
@ -58,14 +60,15 @@ fn type_op_ascribe_user_type<'tcx>(
variance,
def_id,
user_substs,
projs,
},
) = key.into_parts();
debug!(
"type_op_ascribe_user_type(\
mir_ty={:?}, variance={:?}, def_id={:?}, user_substs={:?}\
mir_ty={:?}, variance={:?}, def_id={:?}, user_substs={:?}, projs={:?}\
)",
mir_ty, variance, def_id, user_substs,
mir_ty, variance, def_id, user_substs, projs,
);
let mut cx = AscribeUserTypeCx {
@ -73,7 +76,7 @@ fn type_op_ascribe_user_type<'tcx>(
param_env,
fulfill_cx,
};
cx.relate_mir_and_user_ty(mir_ty, variance, def_id, user_substs)?;
cx.relate_mir_and_user_ty(mir_ty, variance, def_id, user_substs, projs)?;
Ok(())
})
@ -134,17 +137,30 @@ impl AscribeUserTypeCx<'me, 'gcx, 'tcx> {
variance: Variance,
def_id: DefId,
user_substs: UserSubsts<'tcx>,
projs: &[ProjectionKind<'tcx>],
) -> Result<(), NoSolution> {
let UserSubsts {
substs,
user_self_ty,
} = user_substs;
let ty = self.tcx().type_of(def_id);
let tcx = self.tcx();
let ty = tcx.type_of(def_id);
let ty = self.subst(ty, substs);
debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
let ty = self.normalize(ty);
let mut projected_ty = PlaceTy::from_ty(ty);
for proj in projs {
projected_ty = projected_ty.projection_ty_core(
tcx, proj, |this, field, &()| {
let ty = this.field_ty(tcx, field);
self.normalize(ty)
});
}
let ty = projected_ty.to_ty(tcx);
self.relate(mir_ty, variance, ty)?;
if let Some(UserSelfTy {