]> git.lizzy.rs Git - rust.git/commitdiff
Don't do autoderef for path resolution
authorFlorian Diebold <flodiebold@gmail.com>
Thu, 31 Oct 2019 19:01:46 +0000 (20:01 +0100)
committerFlorian Diebold <flodiebold@gmail.com>
Fri, 1 Nov 2019 18:57:08 +0000 (19:57 +0100)
crates/ra_hir/src/ty/method_resolution.rs

index ee0c7b00f3bc7100981303d32ce33be2c2eb378c..332bb14b2c595353fd1a8fc9a11522638a44d764 100644 (file)
@@ -191,27 +191,48 @@ pub(crate) fn iterate_method_candidates<T>(
     mode: LookupMode,
     mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
 ) -> Option<T> {
-    // 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