aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/method_resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/method_resolution.rs')
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs38
1 files changed, 18 insertions, 20 deletions
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 9f65c5fe1..9a571c2aa 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -6,19 +6,17 @@ use std::sync::Arc;
6 6
7use rustc_hash::FxHashMap; 7use rustc_hash::FxHashMap;
8 8
9use ra_db::SourceRootId;
10
11use crate::{ 9use crate::{
12 HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function, 10 HirDatabase, module_tree::ModuleId, Module, Crate, Name, Function,
13 impl_block::{ImplId, ImplBlock, ImplItem}, 11 impl_block::{ImplId, ImplBlock, ImplItem},
14 generics::GenericParams 12 generics::GenericParams,
13 ty::{AdtDef, Ty}
15}; 14};
16use super::Ty;
17 15
18/// This is used as a key for indexing impls. 16/// This is used as a key for indexing impls.
19#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 17#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
20pub enum TyFingerprint { 18pub enum TyFingerprint {
21 Adt(DefId), 19 Adt(AdtDef),
22 // we'll also want to index impls for primitive types etc. 20 // we'll also want to index impls for primitive types etc.
23} 21}
24 22
@@ -37,7 +35,7 @@ impl TyFingerprint {
37#[derive(Debug, PartialEq, Eq)] 35#[derive(Debug, PartialEq, Eq)]
38pub struct CrateImplBlocks { 36pub struct CrateImplBlocks {
39 /// To make sense of the ModuleIds, we need the source root. 37 /// To make sense of the ModuleIds, we need the source root.
40 source_root_id: SourceRootId, 38 krate: Crate,
41 impls: FxHashMap<TyFingerprint, Vec<(ModuleId, ImplId)>>, 39 impls: FxHashMap<TyFingerprint, Vec<(ModuleId, ImplId)>>,
42} 40}
43 41
@@ -53,14 +51,17 @@ impl CrateImplBlocks {
53 .into_iter() 51 .into_iter()
54 .flat_map(|i| i.iter()) 52 .flat_map(|i| i.iter())
55 .map(move |(module_id, impl_id)| { 53 .map(move |(module_id, impl_id)| {
56 let module_impl_blocks = db.impls_in_module(self.source_root_id, *module_id); 54 let module = Module {
55 krate: self.krate.crate_id,
56 module_id: *module_id,
57 };
58 let module_impl_blocks = db.impls_in_module(module);
57 ImplBlock::from_id(module_impl_blocks, *impl_id) 59 ImplBlock::from_id(module_impl_blocks, *impl_id)
58 }) 60 })
59 } 61 }
60 62
61 fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { 63 fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) {
62 let module_id = module.def_id.loc(db).module_id; 64 let module_impl_blocks = db.impls_in_module(module.clone());
63 let module_impl_blocks = db.impls_in_module(self.source_root_id, module_id);
64 65
65 for (impl_id, impl_data) in module_impl_blocks.impls.iter() { 66 for (impl_id, impl_data) in module_impl_blocks.impls.iter() {
66 let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id); 67 let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id);
@@ -81,13 +82,13 @@ impl CrateImplBlocks {
81 self.impls 82 self.impls
82 .entry(target_ty_fp) 83 .entry(target_ty_fp)
83 .or_insert_with(Vec::new) 84 .or_insert_with(Vec::new)
84 .push((module_id, impl_id)); 85 .push((module.module_id, impl_id));
85 } 86 }
86 } 87 }
87 } 88 }
88 89
89 for child in module.children(db) { 90 for child in module.children(db) {
90 self.collect_recursive(db, child); 91 self.collect_recursive(db, &child);
91 } 92 }
92 } 93 }
93 94
@@ -95,15 +96,12 @@ impl CrateImplBlocks {
95 db: &impl HirDatabase, 96 db: &impl HirDatabase,
96 krate: Crate, 97 krate: Crate,
97 ) -> Arc<CrateImplBlocks> { 98 ) -> Arc<CrateImplBlocks> {
98 let crate_graph = db.crate_graph();
99 let file_id = crate_graph.crate_root(krate.crate_id);
100 let source_root_id = db.file_source_root(file_id);
101 let mut crate_impl_blocks = CrateImplBlocks { 99 let mut crate_impl_blocks = CrateImplBlocks {
102 source_root_id, 100 krate: krate.clone(),
103 impls: FxHashMap::default(), 101 impls: FxHashMap::default(),
104 }; 102 };
105 if let Some(module) = krate.root_module(db) { 103 if let Some(module) = krate.root_module(db) {
106 crate_impl_blocks.collect_recursive(db, module); 104 crate_impl_blocks.collect_recursive(db, &module);
107 } 105 }
108 Arc::new(crate_impl_blocks) 106 Arc::new(crate_impl_blocks)
109 } 107 }
@@ -120,11 +118,11 @@ impl Ty {
120 // TODO: cache this as a query? 118 // TODO: cache this as a query?
121 // - if so, what signature? (TyFingerprint, Name)? 119 // - if so, what signature? (TyFingerprint, Name)?
122 // - or maybe cache all names and def_ids of methods per fingerprint? 120 // - or maybe cache all names and def_ids of methods per fingerprint?
123 pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Option<DefId> { 121 pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Option<Function> {
124 self.iterate_methods(db, |f| { 122 self.iterate_methods(db, |f| {
125 let sig = f.signature(db); 123 let sig = f.signature(db);
126 if sig.name() == name && sig.has_self_param() { 124 if sig.name() == name && sig.has_self_param() {
127 Some(f.def_id()) 125 Some(f)
128 } else { 126 } else {
129 None 127 None
130 } 128 }