From 7cfcefd1fbbbfefbdc88feb7359e6364d7c0bf8a Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 27 Aug 2020 12:09:34 +0800 Subject: [PATCH] add projection_ty_from_predicates query --- .../infer/error_reporting/mod.rs | 12 +--------- src/librustc_middle/query/mod.rs | 4 ++++ src/librustc_typeck/check/expr.rs | 10 +------- src/librustc_typeck/check/method/suggest.rs | 14 ++--------- src/librustc_typeck/collect.rs | 23 +++++++++++++++++++ 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> { + desc { |tcx| "finding projection type inside predicates of `{}`", tcx.def_path_str(key.0) } + } + query native_libraries(_: CrateNum) -> Lrc> { 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 `::N` + DefId, + ), +) -> Option> { + 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,