aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs57
1 files changed, 39 insertions, 18 deletions
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<T>(
191 mode: LookupMode, 191 mode: LookupMode,
192 mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, 192 mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
193) -> Option<T> { 193) -> Option<T> {
194 // For method calls, rust first does any number of autoderef, and then one 194 let krate = resolver.krate()?;
195 // autoref (i.e. when the method takes &self or &mut self). We just ignore 195 match mode {
196 // the autoref currently -- when we find a method matching the given name, 196 LookupMode::MethodCall => {
197 // we assume it fits. 197 // For method calls, rust first does any number of autoderef, and then one
198 // autoref (i.e. when the method takes &self or &mut self). We just ignore
199 // the autoref currently -- when we find a method matching the given name,
200 // we assume it fits.
198 201
199 // Also note that when we've got a receiver like &S, even if the method we 202 // Also note that when we've got a receiver like &S, even if the method we
200 // find in the end takes &self, we still do the autoderef step (just as 203 // find in the end takes &self, we still do the autoderef step (just as
201 // rustc does an autoderef and then autoref again). 204 // rustc does an autoderef and then autoref again).
202 205
203 let krate = resolver.krate()?; 206 for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) {
204 // TODO no autoderef in LookupMode::Path 207 if let Some(result) =
205 for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) { 208 iterate_inherent_methods(&derefed_ty, db, name, mode, krate, &mut callback)
206 if let Some(result) = 209 {
207 iterate_inherent_methods(&derefed_ty, db, name, mode, krate, &mut callback) 210 return Some(result);
208 { 211 }
209 return Some(result); 212 if let Some(result) = iterate_trait_method_candidates(
213 &derefed_ty,
214 db,
215 resolver,
216 name,
217 mode,
218 &mut callback,
219 ) {
220 return Some(result);
221 }
222 }
210 } 223 }
211 if let Some(result) = 224 LookupMode::Path => {
212 iterate_trait_method_candidates(&derefed_ty, db, resolver, name, mode, &mut callback) 225 // No autoderef for path lookups
213 { 226 if let Some(result) =
214 return Some(result); 227 iterate_inherent_methods(&ty, db, name, mode, krate, &mut callback)
228 {
229 return Some(result);
230 }
231 if let Some(result) =
232 iterate_trait_method_candidates(&ty, db, resolver, name, mode, &mut callback)
233 {
234 return Some(result);
235 }
215 } 236 }
216 } 237 }
217 None 238 None