aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r--crates/ra_hir/src/code_model.rs94
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};
23use hir_ty::{ 22use 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};
27use ra_db::{CrateId, Edition, FileId}; 26use ra_db::{CrateId, Edition, FileId};
28use ra_prof::profile; 27use ra_prof::profile;
@@ -120,7 +119,8 @@ impl_froms!(
120 BuiltinType 119 BuiltinType
121); 120);
122 121
123pub use hir_def::{attr::Attrs, visibility::Visibility}; 122pub use hir_def::{attr::Attrs, visibility::Visibility, AssocItemId};
123use rustc_hash::FxHashSet;
124 124
125impl Module { 125impl 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())