From f4181deb0dd2cce2184df0057cf349628a70f2e9 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Thu, 31 Oct 2019 20:01:46 +0100 Subject: Don't do autoderef for path resolution --- crates/ra_hir/src/ty/method_resolution.rs | 57 +++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 18 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index ee0c7b00f..332bb14b2 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -191,27 +191,48 @@ pub(crate) fn iterate_method_candidates( mode: LookupMode, mut callback: impl FnMut(&Ty, AssocItem) -> Option, ) -> Option { - // For method calls, rust first does any number of autoderef, and then one - // autoref (i.e. when the method takes &self or &mut self). We just ignore - // the autoref currently -- when we find a method matching the given name, - // we assume it fits. + let krate = resolver.krate()?; + match mode { + LookupMode::MethodCall => { + // For method calls, rust first does any number of autoderef, and then one + // autoref (i.e. when the method takes &self or &mut self). We just ignore + // the autoref currently -- when we find a method matching the given name, + // we assume it fits. - // Also note that when we've got a receiver like &S, even if the method we - // find in the end takes &self, we still do the autoderef step (just as - // rustc does an autoderef and then autoref again). + // Also note that when we've got a receiver like &S, even if the method we + // find in the end takes &self, we still do the autoderef step (just as + // rustc does an autoderef and then autoref again). - let krate = resolver.krate()?; - // TODO no autoderef in LookupMode::Path - for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) { - if let Some(result) = - iterate_inherent_methods(&derefed_ty, db, name, mode, krate, &mut callback) - { - return Some(result); + for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) { + if let Some(result) = + iterate_inherent_methods(&derefed_ty, db, name, mode, krate, &mut callback) + { + return Some(result); + } + if let Some(result) = iterate_trait_method_candidates( + &derefed_ty, + db, + resolver, + name, + mode, + &mut callback, + ) { + return Some(result); + } + } } - if let Some(result) = - iterate_trait_method_candidates(&derefed_ty, db, resolver, name, mode, &mut callback) - { - return Some(result); + LookupMode::Path => { + // No autoderef for path lookups + if let Some(result) = + iterate_inherent_methods(&ty, db, name, mode, krate, &mut callback) + { + return Some(result); + } + if let Some(result) = + iterate_trait_method_candidates(&ty, db, resolver, name, mode, &mut callback) + { + return Some(result); + } } } None -- cgit v1.2.3