diff options
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 94 |
1 files changed, 88 insertions, 6 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index a177cebca..500b34c17 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -7,7 +7,6 @@ use hir_def::{ | |||
7 | builtin_type::BuiltinType, | 7 | builtin_type::BuiltinType, |
8 | docs::Documentation, | 8 | docs::Documentation, |
9 | expr::{BindingAnnotation, Pat, PatId}, | 9 | expr::{BindingAnnotation, Pat, PatId}, |
10 | nameres::ModuleSource, | ||
11 | per_ns::PerNs, | 10 | per_ns::PerNs, |
12 | resolver::HasResolver, | 11 | resolver::HasResolver, |
13 | type_ref::{Mutability, TypeRef}, | 12 | type_ref::{Mutability, TypeRef}, |
@@ -21,8 +20,8 @@ use hir_expand::{ | |||
21 | MacroDefId, | 20 | MacroDefId, |
22 | }; | 21 | }; |
23 | use hir_ty::{ | 22 | use hir_ty::{ |
24 | autoderef, display::HirFormatter, expr::ExprValidator, ApplicationTy, Canonical, InEnvironment, | 23 | autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy, |
25 | TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, | 24 | Canonical, InEnvironment, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, |
26 | }; | 25 | }; |
27 | use ra_db::{CrateId, Edition, FileId}; | 26 | use ra_db::{CrateId, Edition, FileId}; |
28 | use ra_prof::profile; | 27 | use ra_prof::profile; |
@@ -120,7 +119,8 @@ impl_froms!( | |||
120 | BuiltinType | 119 | BuiltinType |
121 | ); | 120 | ); |
122 | 121 | ||
123 | pub use hir_def::{attr::Attrs, visibility::Visibility}; | 122 | pub use hir_def::{attr::Attrs, visibility::Visibility, AssocItemId}; |
123 | use rustc_hash::FxHashSet; | ||
124 | 124 | ||
125 | impl Module { | 125 | impl Module { |
126 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { | 126 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
@@ -192,13 +192,14 @@ impl Module { | |||
192 | 192 | ||
193 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | 193 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
194 | let _p = profile("Module::diagnostics"); | 194 | let _p = profile("Module::diagnostics"); |
195 | db.crate_def_map(self.id.krate).add_diagnostics(db, self.id.local_id, sink); | 195 | let crate_def_map = db.crate_def_map(self.id.krate); |
196 | crate_def_map.add_diagnostics(db, self.id.local_id, sink); | ||
196 | for decl in self.declarations(db) { | 197 | for decl in self.declarations(db) { |
197 | match decl { | 198 | match decl { |
198 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), | 199 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), |
199 | crate::ModuleDef::Module(m) => { | 200 | crate::ModuleDef::Module(m) => { |
200 | // Only add diagnostics from inline modules | 201 | // Only add diagnostics from inline modules |
201 | if let ModuleSource::Module(_) = m.definition_source(db).value { | 202 | if crate_def_map[m.id.local_id].origin.is_inline() { |
202 | m.diagnostics(db, sink) | 203 | m.diagnostics(db, sink) |
203 | } | 204 | } |
204 | } | 205 | } |
@@ -878,6 +879,28 @@ impl Type { | |||
878 | } | 879 | } |
879 | } | 880 | } |
880 | 881 | ||
882 | /// Checks that particular type `ty` implements `std::future::Future`. | ||
883 | /// This function is used in `.await` syntax completion. | ||
884 | pub fn impls_future(&self, db: &impl HirDatabase) -> bool { | ||
885 | let krate = self.krate; | ||
886 | |||
887 | let std_future_trait = | ||
888 | db.lang_item(krate, "future_trait".into()).and_then(|it| it.as_trait()); | ||
889 | let std_future_trait = match std_future_trait { | ||
890 | Some(it) => it, | ||
891 | None => return false, | ||
892 | }; | ||
893 | |||
894 | let canonical_ty = Canonical { value: self.ty.value.clone(), num_vars: 0 }; | ||
895 | method_resolution::implements_trait( | ||
896 | &canonical_ty, | ||
897 | db, | ||
898 | self.ty.environment.clone(), | ||
899 | krate, | ||
900 | std_future_trait, | ||
901 | ) | ||
902 | } | ||
903 | |||
881 | // 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. |
882 | pub fn as_callable(&self) -> Option<CallableDef> { | 905 | pub fn as_callable(&self) -> Option<CallableDef> { |
883 | Some(self.ty.value.as_callable()?.0) | 906 | Some(self.ty.value.as_callable()?.0) |
@@ -986,6 +1009,65 @@ impl Type { | |||
986 | None | 1009 | None |
987 | } | 1010 | } |
988 | 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 | |||
989 | pub fn as_adt(&self) -> Option<Adt> { | 1071 | pub fn as_adt(&self) -> Option<Adt> { |
990 | let (adt, _subst) = self.ty.value.as_adt()?; | 1072 | let (adt, _subst) = self.ty.value.as_adt()?; |
991 | Some(adt.into()) | 1073 | Some(adt.into()) |