Skip to content

Commit

Permalink
add user_ty.projs support to AscribeUserType.
Browse files Browse the repository at this point in the history
  • Loading branch information
pnkfelix committed Oct 26, 2018
1 parent 82ab668 commit 639a3ff
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 10 deletions.
11 changes: 7 additions & 4 deletions src/librustc/traits/query/type_op/ascribe_user_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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> {
Expand All @@ -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 }
}
}

Expand Down Expand Up @@ -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
}
}
4 changes: 2 additions & 2 deletions src/librustc_mir/borrow_check/nll/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)),
)?;
}
Expand Down
24 changes: 20 additions & 4 deletions src/librustc_traits/type_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -58,22 +60,23 @@ 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 {
infcx,
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(())
})
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 639a3ff

Please sign in to comment.