about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2018-10-26 14:00:07 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2018-10-26 23:47:53 +0200
commit639a3ffadcfec5165d434cbbf320678f69b01a5b (patch)
treee6b6825f32bfa97b8bcade106be71229c0f71d31
parent82ab668a556abc1843e10bb0da2a307d2442e1e2 (diff)
downloadrust-639a3ffadcfec5165d434cbbf320678f69b01a5b.tar.gz
rust-639a3ffadcfec5165d434cbbf320678f69b01a5b.zip
add user_ty.projs support to `AscribeUserType`.
-rw-r--r--src/librustc/traits/query/type_op/ascribe_user_type.rs11
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs4
-rw-r--r--src/librustc_traits/type_op.rs24
3 files changed, 29 insertions, 10 deletions
diff --git a/src/librustc/traits/query/type_op/ascribe_user_type.rs b/src/librustc/traits/query/type_op/ascribe_user_type.rs
index b3955b8f864..23445781eb2 100644
--- a/src/librustc/traits/query/type_op/ascribe_user_type.rs
+++ b/src/librustc/traits/query/type_op/ascribe_user_type.rs
@@ -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
     }
 }
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 4d1eea4724b..953fe0c9521 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -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,
                     )),
                 )?;
             }
diff --git a/src/librustc_traits/type_op.rs b/src/librustc_traits/type_op.rs
index cf274a9c851..2ed02a4cdab 100644
--- a/src/librustc_traits/type_op.rs
+++ b/src/librustc_traits/type_op.rs
@@ -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 {