diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 74 | ||||
-rw-r--r-- | crates/ra_hir/src/source_analyzer.rs | 56 |
2 files changed, 78 insertions, 52 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 346118350..3b479356f 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -21,8 +21,8 @@ use hir_expand::{ | |||
21 | MacroDefId, | 21 | MacroDefId, |
22 | }; | 22 | }; |
23 | use hir_ty::{ | 23 | use hir_ty::{ |
24 | autoderef, display::HirFormatter, expr::ExprValidator, method_resolution::implements_trait, | 24 | autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy, |
25 | ApplicationTy, Canonical, InEnvironment, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, | 25 | Canonical, InEnvironment, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, |
26 | }; | 26 | }; |
27 | use ra_db::{CrateId, Edition, FileId}; | 27 | use ra_db::{CrateId, Edition, FileId}; |
28 | use ra_prof::profile; | 28 | use ra_prof::profile; |
@@ -120,7 +120,8 @@ impl_froms!( | |||
120 | BuiltinType | 120 | BuiltinType |
121 | ); | 121 | ); |
122 | 122 | ||
123 | pub use hir_def::{attr::Attrs, visibility::Visibility}; | 123 | pub use hir_def::{attr::Attrs, visibility::Visibility, AssocItemId}; |
124 | use rustc_hash::FxHashSet; | ||
124 | 125 | ||
125 | impl Module { | 126 | impl Module { |
126 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { | 127 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
@@ -891,7 +892,13 @@ impl Type { | |||
891 | }; | 892 | }; |
892 | 893 | ||
893 | let canonical_ty = Canonical { value: self.ty.value.clone(), num_vars: 0 }; | 894 | let canonical_ty = Canonical { value: self.ty.value.clone(), num_vars: 0 }; |
894 | implements_trait(&canonical_ty, db, self.ty.environment.clone(), krate, std_future_trait) | 895 | method_resolution::implements_trait( |
896 | &canonical_ty, | ||
897 | db, | ||
898 | self.ty.environment.clone(), | ||
899 | krate, | ||
900 | std_future_trait, | ||
901 | ) | ||
895 | } | 902 | } |
896 | 903 | ||
897 | // FIXME: this method is broken, as it doesn't take closures into account. | 904 | // FIXME: this method is broken, as it doesn't take closures into account. |
@@ -1002,6 +1009,65 @@ impl Type { | |||
1002 | None | 1009 | None |
1003 | } | 1010 | } |
1004 | 1011 | ||
1012 | pub fn iterate_method_candidates<T>( | ||
1013 | &self, | ||
1014 | db: &impl HirDatabase, | ||
1015 | krate: Crate, | ||
1016 | traits_in_scope: &FxHashSet<TraitId>, | ||
1017 | name: Option<&Name>, | ||
1018 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, | ||
1019 | ) -> Option<T> { | ||
1020 | // There should be no inference vars in types passed here | ||
1021 | // FIXME check that? | ||
1022 | // FIXME replace Unknown by bound vars here | ||
1023 | let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; | ||
1024 | |||
1025 | let env = self.ty.environment.clone(); | ||
1026 | let krate = krate.id; | ||
1027 | |||
1028 | method_resolution::iterate_method_candidates( | ||
1029 | &canonical, | ||
1030 | db, | ||
1031 | env, | ||
1032 | krate, | ||
1033 | traits_in_scope, | ||
1034 | name, | ||
1035 | method_resolution::LookupMode::MethodCall, | ||
1036 | |ty, it| match it { | ||
1037 | AssocItemId::FunctionId(f) => callback(ty, f.into()), | ||
1038 | _ => None, | ||
1039 | }, | ||
1040 | ) | ||
1041 | } | ||
1042 | |||
1043 | pub fn iterate_path_candidates<T>( | ||
1044 | &self, | ||
1045 | db: &impl HirDatabase, | ||
1046 | krate: Crate, | ||
1047 | traits_in_scope: &FxHashSet<TraitId>, | ||
1048 | name: Option<&Name>, | ||
1049 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | ||
1050 | ) -> Option<T> { | ||
1051 | // There should be no inference vars in types passed here | ||
1052 | // FIXME check that? | ||
1053 | // FIXME replace Unknown by bound vars here | ||
1054 | let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; | ||
1055 | |||
1056 | let env = self.ty.environment.clone(); | ||
1057 | let krate = krate.id; | ||
1058 | |||
1059 | method_resolution::iterate_method_candidates( | ||
1060 | &canonical, | ||
1061 | db, | ||
1062 | env, | ||
1063 | krate, | ||
1064 | traits_in_scope, | ||
1065 | name, | ||
1066 | method_resolution::LookupMode::Path, | ||
1067 | |ty, it| callback(ty, it.into()), | ||
1068 | ) | ||
1069 | } | ||
1070 | |||
1005 | pub fn as_adt(&self) -> Option<Adt> { | 1071 | pub fn as_adt(&self) -> Option<Adt> { |
1006 | let (adt, _subst) = self.ty.value.as_adt()?; | 1072 | let (adt, _subst) = self.ty.value.as_adt()?; |
1007 | Some(adt.into()) | 1073 | Some(adt.into()) |
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs index 3df48842d..76e0bff34 100644 --- a/crates/ra_hir/src/source_analyzer.rs +++ b/crates/ra_hir/src/source_analyzer.rs | |||
@@ -16,12 +16,12 @@ use hir_def::{ | |||
16 | expr::{ExprId, PatId}, | 16 | expr::{ExprId, PatId}, |
17 | nameres::ModuleSource, | 17 | nameres::ModuleSource, |
18 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, | 18 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, |
19 | AssocItemId, DefWithBodyId, | 19 | DefWithBodyId, TraitId, |
20 | }; | 20 | }; |
21 | use hir_expand::{ | 21 | use hir_expand::{ |
22 | hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, | 22 | hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, |
23 | }; | 23 | }; |
24 | use hir_ty::{method_resolution, Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty}; | 24 | use hir_ty::{InEnvironment, InferenceResult, TraitEnvironment}; |
25 | use ra_prof::profile; | 25 | use ra_prof::profile; |
26 | use ra_syntax::{ | 26 | use ra_syntax::{ |
27 | ast::{self, AstNode}, | 27 | ast::{self, AstNode}, |
@@ -29,11 +29,11 @@ use ra_syntax::{ | |||
29 | SyntaxKind::*, | 29 | SyntaxKind::*, |
30 | SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextUnit, | 30 | SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextUnit, |
31 | }; | 31 | }; |
32 | use rustc_hash::FxHashSet; | ||
32 | 33 | ||
33 | use crate::{ | 34 | use crate::{ |
34 | db::HirDatabase, Adt, AssocItem, Const, DefWithBody, Enum, EnumVariant, FromSource, Function, | 35 | db::HirDatabase, Adt, Const, DefWithBody, Enum, EnumVariant, FromSource, Function, ImplBlock, |
35 | ImplBlock, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, | 36 | Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, |
36 | TypeParam, | ||
37 | }; | 37 | }; |
38 | 38 | ||
39 | /// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of | 39 | /// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of |
@@ -347,49 +347,9 @@ impl SourceAnalyzer { | |||
347 | .collect() | 347 | .collect() |
348 | } | 348 | } |
349 | 349 | ||
350 | pub fn iterate_method_candidates<T>( | 350 | /// Note: `FxHashSet<TraitId>` should be treated as an opaque type, passed into `Type |
351 | &self, | 351 | pub fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<TraitId> { |
352 | db: &impl HirDatabase, | 352 | self.resolver.traits_in_scope(db) |
353 | ty: &Type, | ||
354 | name: Option<&Name>, | ||
355 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, | ||
356 | ) -> Option<T> { | ||
357 | // There should be no inference vars in types passed here | ||
358 | // FIXME check that? | ||
359 | // FIXME replace Unknown by bound vars here | ||
360 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; | ||
361 | method_resolution::iterate_method_candidates( | ||
362 | &canonical, | ||
363 | db, | ||
364 | &self.resolver, | ||
365 | name, | ||
366 | method_resolution::LookupMode::MethodCall, | ||
367 | |ty, it| match it { | ||
368 | AssocItemId::FunctionId(f) => callback(ty, f.into()), | ||
369 | _ => None, | ||
370 | }, | ||
371 | ) | ||
372 | } | ||
373 | |||
374 | pub fn iterate_path_candidates<T>( | ||
375 | &self, | ||
376 | db: &impl HirDatabase, | ||
377 | ty: &Type, | ||
378 | name: Option<&Name>, | ||
379 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | ||
380 | ) -> Option<T> { | ||
381 | // There should be no inference vars in types passed here | ||
382 | // FIXME check that? | ||
383 | // FIXME replace Unknown by bound vars here | ||
384 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; | ||
385 | method_resolution::iterate_method_candidates( | ||
386 | &canonical, | ||
387 | db, | ||
388 | &self.resolver, | ||
389 | name, | ||
390 | method_resolution::LookupMode::Path, | ||
391 | |ty, it| callback(ty, it.into()), | ||
392 | ) | ||
393 | } | 353 | } |
394 | 354 | ||
395 | pub fn expand( | 355 | pub fn expand( |