diff options
Diffstat (limited to 'crates/ra_hir/src/source_binder.rs')
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 152bc71bd..a4ca59bba 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -27,9 +27,9 @@ use crate::{ | |||
27 | }, | 27 | }, |
28 | ids::LocationCtx, | 28 | ids::LocationCtx, |
29 | resolve::{ScopeDef, TypeNs, ValueNs}, | 29 | resolve::{ScopeDef, TypeNs, ValueNs}, |
30 | ty::method_resolution::implements_trait, | 30 | ty::method_resolution::{self, implements_trait}, |
31 | Const, DefWithBody, Either, Enum, FromSource, Function, HasBody, HirFileId, MacroDef, Module, | 31 | AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, HasBody, HirFileId, |
32 | Name, Path, Resolver, Static, Struct, Ty, | 32 | MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | fn try_get_resolver_for_node( | 35 | fn try_get_resolver_for_node( |
@@ -255,7 +255,9 @@ impl SourceAnalyzer { | |||
255 | 255 | ||
256 | let items = | 256 | let items = |
257 | self.resolver.resolve_module_path(db, &path).take_types().map(PathResolution::Def); | 257 | self.resolver.resolve_module_path(db, &path).take_types().map(PathResolution::Def); |
258 | types.or(values).or(items) | 258 | types.or(values).or(items).or_else(|| { |
259 | self.resolver.resolve_path_as_macro(db, &path).map(|def| PathResolution::Macro(def)) | ||
260 | }) | ||
259 | } | 261 | } |
260 | 262 | ||
261 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &ast::Path) -> Option<PathResolution> { | 263 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &ast::Path) -> Option<PathResolution> { |
@@ -325,16 +327,42 @@ impl SourceAnalyzer { | |||
325 | db: &impl HirDatabase, | 327 | db: &impl HirDatabase, |
326 | ty: Ty, | 328 | ty: Ty, |
327 | name: Option<&Name>, | 329 | name: Option<&Name>, |
328 | callback: impl FnMut(&Ty, Function) -> Option<T>, | 330 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, |
331 | ) -> Option<T> { | ||
332 | // There should be no inference vars in types passed here | ||
333 | // FIXME check that? | ||
334 | // FIXME replace Unknown by bound vars here | ||
335 | let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; | ||
336 | method_resolution::iterate_method_candidates( | ||
337 | &canonical, | ||
338 | db, | ||
339 | &self.resolver, | ||
340 | name, | ||
341 | method_resolution::LookupMode::MethodCall, | ||
342 | |ty, it| match it { | ||
343 | AssocItem::Function(f) => callback(ty, f), | ||
344 | _ => None, | ||
345 | }, | ||
346 | ) | ||
347 | } | ||
348 | |||
349 | pub fn iterate_path_candidates<T>( | ||
350 | &self, | ||
351 | db: &impl HirDatabase, | ||
352 | ty: Ty, | ||
353 | name: Option<&Name>, | ||
354 | callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | ||
329 | ) -> Option<T> { | 355 | ) -> Option<T> { |
330 | // There should be no inference vars in types passed here | 356 | // There should be no inference vars in types passed here |
331 | // FIXME check that? | 357 | // FIXME check that? |
358 | // FIXME replace Unknown by bound vars here | ||
332 | let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; | 359 | let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; |
333 | crate::ty::method_resolution::iterate_method_candidates( | 360 | method_resolution::iterate_method_candidates( |
334 | &canonical, | 361 | &canonical, |
335 | db, | 362 | db, |
336 | &self.resolver, | 363 | &self.resolver, |
337 | name, | 364 | name, |
365 | method_resolution::LookupMode::Path, | ||
338 | callback, | 366 | callback, |
339 | ) | 367 | ) |
340 | } | 368 | } |