about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorcsmoe <csmoe@msn.com>2020-08-27 12:09:34 +0800
committercsmoe <csmoe@msn.com>2020-08-27 12:09:34 +0800
commit7cfcefd1fbbbfefbdc88feb7359e6364d7c0bf8a (patch)
tree14a744cd7272d1a3b0034004be3fc549fb83c583 /src
parent8ee206a80dab320ee76a2aa9324c587368df3921 (diff)
downloadrust-7cfcefd1fbbbfefbdc88feb7359e6364d7c0bf8a.tar.gz
rust-7cfcefd1fbbbfefbdc88feb7359e6364d7c0bf8a.zip
add projection_ty_from_predicates query
Diffstat (limited to 'src')
-rw-r--r--src/librustc_infer/infer/error_reporting/mod.rs12
-rw-r--r--src/librustc_middle/query/mod.rs4
-rw-r--r--src/librustc_typeck/check/expr.rs10
-rw-r--r--src/librustc_typeck/check/method/suggest.rs14
-rw-r--r--src/librustc_typeck/collect.rs23
5 files changed, 31 insertions, 32 deletions
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index 35b2d7e8468..d72ed72e3a8 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -1574,17 +1574,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 .unwrap()
                 .def_id;
 
-            let mut projection_ty = None;
-            for (predicate, _) in self.tcx.predicates_of(def_id).predicates {
-                if let ty::PredicateAtom::Projection(projection_predicate) =
-                    predicate.skip_binders()
-                {
-                    if item_def_id == projection_predicate.projection_ty.item_def_id {
-                        projection_ty = Some(projection_predicate.projection_ty);
-                        break;
-                    }
-                }
-            }
+            let projection_ty = self.tcx.projection_ty_from_predicates((def_id, item_def_id));
             if let Some(projection_ty) = projection_ty {
                 let projection_query = self.canonicalize_query(
                     &ParamEnvAnd { param_env: self.tcx.param_env(def_id), value: projection_ty },
diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs
index d6836d2ee36..e05752f08f6 100644
--- a/src/librustc_middle/query/mod.rs
+++ b/src/librustc_middle/query/mod.rs
@@ -173,6 +173,10 @@ rustc_queries! {
             desc { |tcx| "finding projection predicates for `{}`", tcx.def_path_str(key) }
         }
 
+        query projection_ty_from_predicates(key: (DefId, DefId)) -> Option<ty::ProjectionTy<'tcx>> {
+            desc { |tcx| "finding projection type inside predicates of `{}`", tcx.def_path_str(key.0) }
+        }
+
         query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLib>> {
             desc { "looking up the native libraries of a linked crate" }
         }
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 702dc30957c..82ed8fda8b4 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1523,15 +1523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let item_def_id =
             self.tcx.associated_items(future_trait).in_definition_order().next().unwrap().def_id;
 
-        let mut projection_ty = None;
-        for (predicate, _) in self.tcx.predicates_of(def_id).predicates {
-            if let ty::PredicateAtom::Projection(projection_predicate) = predicate.skip_binders() {
-                if item_def_id == projection_predicate.projection_ty.item_def_id {
-                    projection_ty = Some(projection_predicate.projection_ty);
-                    break;
-                }
-            }
-        }
+        let projection_ty = self.tcx.projection_ty_from_predicates((def_id, item_def_id));
         debug!("suggest_await_on_field_access: projection_ty={:?}", projection_ty);
 
         let cause = self.misc(expr.span);
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 3dd4c7c1439..5cae66bc5da 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -870,7 +870,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         call: &hir::Expr<'_>,
         span: Span,
     ) {
-        if let ty::Opaque(def_id, _substs) = ty.kind {
+        if let ty::Opaque(def_id, _) = ty.kind {
             let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
             // Future::Output
             let item_def_id = self
@@ -881,17 +881,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .unwrap()
                 .def_id;
 
-            let mut projection_ty = None;
-            for (predicate, _) in self.tcx.predicates_of(def_id).predicates {
-                if let ty::PredicateAtom::Projection(projection_predicate) =
-                    predicate.skip_binders()
-                {
-                    if item_def_id == projection_predicate.projection_ty.item_def_id {
-                        projection_ty = Some(projection_predicate.projection_ty);
-                        break;
-                    }
-                }
-            }
+            let projection_ty = self.tcx.projection_ty_from_predicates((def_id, item_def_id));
             let cause = self.misc(span);
             let mut selcx = SelectionContext::new(&self.infcx);
             let mut obligations = vec![];
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 1b472810ccf..7a3f7ec56a2 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -70,6 +70,7 @@ pub fn provide(providers: &mut Providers) {
         generics_of,
         predicates_of,
         predicates_defined_on,
+        projection_ty_from_predicates,
         explicit_predicates_of,
         super_predicates_of,
         type_param_predicates,
@@ -2051,6 +2052,28 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
     result
 }
 
+fn projection_ty_from_predicates(
+    tcx: TyCtxt<'tcx>,
+    key: (
+        // ty_def_id
+        DefId,
+        // def_id of `N` in `<T as Trait>::N`
+        DefId,
+    ),
+) -> Option<ty::ProjectionTy<'tcx>> {
+    let (ty_def_id, item_def_id) = key;
+    let mut projection_ty = None;
+    for (predicate, _) in tcx.predicates_of(ty_def_id).predicates {
+        if let ty::PredicateAtom::Projection(projection_predicate) = predicate.skip_binders() {
+            if item_def_id == projection_predicate.projection_ty.item_def_id {
+                projection_ty = Some(projection_predicate.projection_ty);
+                break;
+            }
+        }
+    }
+    projection_ty
+}
+
 fn trait_associated_item_predicates(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,