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/source_binder.rs15
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs67
2 files changed, 62 insertions, 20 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index d1eaccf23..a1b94ed9c 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -14,7 +14,7 @@ use ra_syntax::{
14 14
15use crate::{ 15use crate::{
16 HirDatabase, Function, ModuleDef, Struct, Enum, 16 HirDatabase, Function, ModuleDef, Struct, Enum,
17 AsName, Module, HirFileId, Crate, 17 AsName, Module, HirFileId, Crate, Trait,
18 ids::{LocationCtx, SourceFileItemId}, 18 ids::{LocationCtx, SourceFileItemId},
19}; 19};
20 20
@@ -151,6 +151,19 @@ pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::E
151 } 151 }
152} 152}
153 153
154pub fn trait_from_module(
155 db: &impl HirDatabase,
156 module: Module,
157 trait_def: &ast::TraitDef,
158) -> Trait {
159 let (file_id, _) = module.definition_source(db);
160 let file_id = file_id.into();
161 let ctx = LocationCtx::new(db, module, file_id);
162 Trait {
163 id: ctx.to_def(trait_def),
164 }
165}
166
154pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> { 167pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> {
155 let module = match module_from_file_id(db, file_id) { 168 let module = match module_from_file_id(db, file_id) {
156 Some(it) => it, 169 Some(it) => it,
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 37bc3f38c..e857d6856 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -7,17 +7,18 @@ use std::sync::Arc;
7use rustc_hash::FxHashMap; 7use rustc_hash::FxHashMap;
8 8
9use crate::{ 9use crate::{
10 HirDatabase, module_tree::ModuleId, Module, Crate, Name, Function, 10 HirDatabase, module_tree::ModuleId, Module, ModuleDef, Crate, Name, Function, Trait,
11 ids::TraitId,
11 impl_block::{ImplId, ImplBlock, ImplItem}, 12 impl_block::{ImplId, ImplBlock, ImplItem},
12 generics::GenericParams, 13 generics::GenericParams,
13 ty::{AdtDef, Ty} 14 ty::{AdtDef, Ty},
15 type_ref::TypeRef,
14}; 16};
15 17
16/// This is used as a key for indexing impls. 18/// This is used as a key for indexing impls.
17#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 19#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
18pub enum TyFingerprint { 20pub enum TyFingerprint {
19 Adt(AdtDef), 21 Adt(AdtDef), // we'll also want to index impls for primitive types etc.
20 // we'll also want to index impls for primitive types etc.
21} 22}
22 23
23impl TyFingerprint { 24impl TyFingerprint {
@@ -37,6 +38,7 @@ pub struct CrateImplBlocks {
37 /// To make sense of the ModuleIds, we need the source root. 38 /// To make sense of the ModuleIds, we need the source root.
38 krate: Crate, 39 krate: Crate,
39 impls: FxHashMap<TyFingerprint, Vec<(ModuleId, ImplId)>>, 40 impls: FxHashMap<TyFingerprint, Vec<(ModuleId, ImplId)>>,
41 impls_by_trait: FxHashMap<TraitId, Vec<(ModuleId, ImplId)>>,
40} 42}
41 43
42impl CrateImplBlocks { 44impl CrateImplBlocks {
@@ -60,27 +62,53 @@ impl CrateImplBlocks {
60 }) 62 })
61 } 63 }
62 64
65 pub fn lookup_impl_blocks_for_trait<'a>(
66 &'a self,
67 db: &'a impl HirDatabase,
68 tr: &Trait,
69 ) -> impl Iterator<Item = (Module, ImplBlock)> + 'a {
70 let id = tr.id;
71 self.impls_by_trait
72 .get(&id)
73 .into_iter()
74 .flat_map(|i| i.iter())
75 .map(move |(module_id, impl_id)| {
76 let module = Module {
77 krate: self.krate,
78 module_id: *module_id,
79 };
80 let module_impl_blocks = db.impls_in_module(module);
81 (module, ImplBlock::from_id(module_impl_blocks, *impl_id))
82 })
83 }
84
63 fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) { 85 fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) {
64 let module_impl_blocks = db.impls_in_module(module.clone()); 86 let module_impl_blocks = db.impls_in_module(module.clone());
65 87
66 for (impl_id, impl_data) in module_impl_blocks.impls.iter() { 88 for (impl_id, impl_data) in module_impl_blocks.impls.iter() {
67 let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id); 89 let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id);
90 // TODO provide generics of impl
91 let generics = GenericParams::default();
92 let target_ty = Ty::from_hir(
93 db,
94 &module,
95 Some(&impl_block),
96 &generics,
97 impl_data.target_type(),
98 );
99
100 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
101 self.impls
102 .entry(target_ty_fp)
103 .or_insert_with(Vec::new)
104 .push((module.module_id, impl_id));
105 }
68 106
69 if let Some(_target_trait) = impl_data.target_trait() { 107 if let Some(TypeRef::Path(path)) = impl_data.target_trait() {
70 // ignore for now 108 let perns = module.resolve_path(db, path);
71 } else { 109 if let Some(ModuleDef::Trait(tr)) = perns.take_types() {
72 // TODO provide generics of impl 110 self.impls_by_trait
73 let generics = GenericParams::default(); 111 .entry(tr.id)
74 let target_ty = Ty::from_hir(
75 db,
76 &module,
77 Some(&impl_block),
78 &generics,
79 impl_data.target_type(),
80 );
81 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
82 self.impls
83 .entry(target_ty_fp)
84 .or_insert_with(Vec::new) 112 .or_insert_with(Vec::new)
85 .push((module.module_id, impl_id)); 113 .push((module.module_id, impl_id));
86 } 114 }
@@ -99,6 +127,7 @@ impl CrateImplBlocks {
99 let mut crate_impl_blocks = CrateImplBlocks { 127 let mut crate_impl_blocks = CrateImplBlocks {
100 krate: krate.clone(), 128 krate: krate.clone(),
101 impls: FxHashMap::default(), 129 impls: FxHashMap::default(),
130 impls_by_trait: FxHashMap::default(),
102 }; 131 };
103 if let Some(module) = krate.root_module(db) { 132 if let Some(module) = krate.root_module(db) {
104 crate_impl_blocks.collect_recursive(db, &module); 133 crate_impl_blocks.collect_recursive(db, &module);