From 7ec62ea5e686dcb6de5d3fcc413f32af9d1c9cb5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 14 Jan 2020 14:11:07 +0100 Subject: Push resolver up --- crates/ra_hir_ty/src/method_resolution.rs | 72 ++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 21 deletions(-) (limited to 'crates/ra_hir_ty/src') diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index 55435e6ea..e43fadf20 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs @@ -12,7 +12,7 @@ use hir_def::{ use hir_expand::name::Name; use ra_db::CrateId; use ra_prof::profile; -use rustc_hash::FxHashMap; +use rustc_hash::{FxHashMap, FxHashSet}; use super::Substs; use crate::{ @@ -177,6 +177,9 @@ pub fn iterate_method_candidates( mode: LookupMode, mut callback: impl FnMut(&Ty, AssocItemId) -> Option, ) -> Option { + let traits_in_scope = resolver.traits_in_scope(db); + let krate = resolver.krate()?; + let env = TraitEnvironment::lower(db, resolver); match mode { LookupMode::MethodCall => { // For method calls, rust first does any number of autoderef, and then one @@ -209,7 +212,9 @@ pub fn iterate_method_candidates( if let Some(result) = iterate_method_candidates_with_autoref( &deref_chain[i..], db, - resolver, + env.clone(), + krate, + &traits_in_scope, name, &mut callback, ) { @@ -220,7 +225,15 @@ pub fn iterate_method_candidates( } LookupMode::Path => { // No autoderef for path lookups - iterate_method_candidates_for_self_ty(&ty, db, resolver, name, &mut callback) + iterate_method_candidates_for_self_ty( + &ty, + db, + env, + krate, + &traits_in_scope, + name, + &mut callback, + ) } } } @@ -228,7 +241,9 @@ pub fn iterate_method_candidates( fn iterate_method_candidates_with_autoref( deref_chain: &[Canonical], db: &impl HirDatabase, - resolver: &Resolver, + env: Arc, + krate: CrateId, + traits_in_scope: &FxHashSet, name: Option<&Name>, mut callback: impl FnMut(&Ty, AssocItemId) -> Option, ) -> Option { @@ -236,7 +251,9 @@ fn iterate_method_candidates_with_autoref( &deref_chain[0], &deref_chain[1..], db, - resolver, + env.clone(), + krate, + &traits_in_scope, name, &mut callback, ) { @@ -250,7 +267,9 @@ fn iterate_method_candidates_with_autoref( &refed, deref_chain, db, - resolver, + env.clone(), + krate, + &traits_in_scope, name, &mut callback, ) { @@ -264,7 +283,9 @@ fn iterate_method_candidates_with_autoref( &ref_muted, deref_chain, db, - resolver, + env.clone(), + krate, + &traits_in_scope, name, &mut callback, ) { @@ -277,14 +298,15 @@ fn iterate_method_candidates_by_receiver( receiver_ty: &Canonical, rest_of_deref_chain: &[Canonical], db: &impl HirDatabase, - resolver: &Resolver, + env: Arc, + krate: CrateId, + traits_in_scope: &FxHashSet, name: Option<&Name>, mut callback: impl FnMut(&Ty, AssocItemId) -> Option, ) -> Option { // We're looking for methods with *receiver* type receiver_ty. These could // be found in any of the derefs of receiver_ty, so we have to go through // that. - let krate = resolver.krate()?; for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) { if let Some(result) = iterate_inherent_methods(self_ty, db, name, Some(receiver_ty), krate, &mut callback) @@ -296,7 +318,9 @@ fn iterate_method_candidates_by_receiver( if let Some(result) = iterate_trait_method_candidates( self_ty, db, - resolver, + env.clone(), + krate, + &traits_in_scope, name, Some(receiver_ty), &mut callback, @@ -310,17 +334,25 @@ fn iterate_method_candidates_by_receiver( fn iterate_method_candidates_for_self_ty( self_ty: &Canonical, db: &impl HirDatabase, - resolver: &Resolver, + env: Arc, + krate: CrateId, + traits_in_scope: &FxHashSet, name: Option<&Name>, mut callback: impl FnMut(&Ty, AssocItemId) -> Option, ) -> Option { - let krate = resolver.krate()?; if let Some(result) = iterate_inherent_methods(self_ty, db, name, None, krate, &mut callback) { return Some(result); } - if let Some(result) = - iterate_trait_method_candidates(self_ty, db, resolver, name, None, &mut callback) - { + if let Some(result) = iterate_trait_method_candidates( + self_ty, + db, + env, + krate, + traits_in_scope, + name, + None, + &mut callback, + ) { return Some(result); } None @@ -329,14 +361,13 @@ fn iterate_method_candidates_for_self_ty( fn iterate_trait_method_candidates( self_ty: &Canonical, db: &impl HirDatabase, - resolver: &Resolver, + env: Arc, + krate: CrateId, + traits_in_scope: &FxHashSet, name: Option<&Name>, receiver_ty: Option<&Canonical>, mut callback: impl FnMut(&Ty, AssocItemId) -> Option, ) -> Option { - let krate = resolver.krate()?; - // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that) - let env = TraitEnvironment::lower(db, resolver); // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope let inherent_trait = self_ty.value.inherent_trait().into_iter(); // if we have `T: Trait` in the param env, the trait doesn't need to be in scope @@ -344,8 +375,7 @@ fn iterate_trait_method_candidates( .trait_predicates_for_self_ty(&self_ty.value) .map(|tr| tr.trait_) .flat_map(|t| all_super_traits(db, t)); - let traits = - inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db).into_iter()); + let traits = inherent_trait.chain(traits_from_env).chain(traits_in_scope.iter().copied()); 'traits: for t in traits { let data = db.trait_data(t); -- cgit v1.2.3