aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/db.rs8
-rw-r--r--crates/ra_hir/src/ids.rs5
-rw-r--r--crates/ra_hir/src/impl_block.rs52
3 files changed, 32 insertions, 33 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 6d5235ba4..a045bbb12 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -4,7 +4,7 @@ use ra_syntax::{SyntaxNode, SourceFileNode};
4use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable}; 4use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable};
5 5
6use crate::{ 6use crate::{
7 Crate, DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId, 7 DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId,
8 SourceFileItems, SourceItemId, 8 SourceFileItems, SourceItemId,
9 query_definitions, 9 query_definitions,
10 FnScopes, 10 FnScopes,
@@ -13,7 +13,7 @@ use crate::{
13 nameres::{ItemMap, InputModuleItems}}, 13 nameres::{ItemMap, InputModuleItems}},
14 ty::{InferenceResult, Ty}, 14 ty::{InferenceResult, Ty},
15 adt::{StructData, EnumData}, 15 adt::{StructData, EnumData},
16 impl_block::CrateImplBlocks, 16 impl_block::ModuleImplBlocks,
17}; 17};
18 18
19salsa::query_group! { 19salsa::query_group! {
@@ -89,9 +89,9 @@ pub trait HirDatabase: SyntaxDatabase
89 use fn crate::module::imp::module_tree; 89 use fn crate::module::imp::module_tree;
90 } 90 }
91 91
92 fn impls_in_crate(krate: Crate) -> Cancelable<Arc<CrateImplBlocks>> { 92 fn impls_in_module(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<ModuleImplBlocks>> {
93 type ImplsInCrateQuery; 93 type ImplsInCrateQuery;
94 use fn crate::impl_block::impls_in_crate; 94 use fn crate::impl_block::impls_in_module;
95 } 95 }
96} 96}
97 97
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index c98be66f9..4d6378e02 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -185,8 +185,9 @@ impl DefId {
185 185
186 /// Returns the containing impl block, if this is an impl item. 186 /// Returns the containing impl block, if this is an impl item.
187 pub fn impl_block(self, db: &impl HirDatabase) -> Cancelable<Option<ImplBlock>> { 187 pub fn impl_block(self, db: &impl HirDatabase) -> Cancelable<Option<ImplBlock>> {
188 let crate_impls = db.impls_in_crate(ctry!(self.krate(db)?))?; 188 let loc = self.loc(db);
189 Ok(ImplBlock::containing(crate_impls, self)) 189 let module_impls = db.impls_in_module(loc.source_root_id, loc.module_id)?;
190 Ok(ImplBlock::containing(module_impls, self))
190 } 191 }
191} 192}
192 193
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 77fab24d0..01afa84c4 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -3,36 +3,36 @@ use rustc_hash::FxHashMap;
3 3
4use ra_arena::{Arena, RawId, impl_arena_id}; 4use ra_arena::{Arena, RawId, impl_arena_id};
5use ra_syntax::ast::{self, AstNode}; 5use ra_syntax::ast::{self, AstNode};
6use ra_db::{LocationIntener, Cancelable}; 6use ra_db::{LocationIntener, Cancelable, SourceRootId};
7 7
8use crate::{ 8use crate::{
9 Crate, DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, 9 DefId, DefLoc, DefKind, SourceItemId, SourceFileItems,
10 Module, Function, 10 Module, Function,
11 db::HirDatabase, 11 db::HirDatabase,
12 type_ref::TypeRef, 12 type_ref::TypeRef,
13 module::{ModuleSourceNode}, 13 module::{ModuleSourceNode, ModuleId},
14}; 14};
15 15
16#[derive(Debug, Clone, PartialEq, Eq)] 16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct ImplBlock { 17pub struct ImplBlock {
18 crate_impl_blocks: Arc<CrateImplBlocks>, 18 module_impl_blocks: Arc<ModuleImplBlocks>,
19 impl_id: ImplId, 19 impl_id: ImplId,
20} 20}
21 21
22impl ImplBlock { 22impl ImplBlock {
23 pub(crate) fn containing( 23 pub(crate) fn containing(
24 crate_impl_blocks: Arc<CrateImplBlocks>, 24 module_impl_blocks: Arc<ModuleImplBlocks>,
25 def_id: DefId, 25 def_id: DefId,
26 ) -> Option<ImplBlock> { 26 ) -> Option<ImplBlock> {
27 let impl_id = *crate_impl_blocks.impls_by_def.get(&def_id)?; 27 let impl_id = *module_impl_blocks.impls_by_def.get(&def_id)?;
28 Some(ImplBlock { 28 Some(ImplBlock {
29 crate_impl_blocks, 29 module_impl_blocks,
30 impl_id, 30 impl_id,
31 }) 31 })
32 } 32 }
33 33
34 fn impl_data(&self) -> &ImplData { 34 fn impl_data(&self) -> &ImplData {
35 &self.crate_impl_blocks.impls[self.impl_id] 35 &self.module_impl_blocks.impls[self.impl_id]
36 } 36 }
37 37
38 pub fn target_trait(&self) -> Option<&TypeRef> { 38 pub fn target_trait(&self) -> Option<&TypeRef> {
@@ -126,17 +126,22 @@ impl ImplItem {
126pub struct ImplId(pub RawId); 126pub struct ImplId(pub RawId);
127impl_arena_id!(ImplId); 127impl_arena_id!(ImplId);
128 128
129/// We have to collect all impl blocks in a crate, to later be able to find 129/// Collection of impl blocks is a two-step process: First we collect the blocks
130/// impls for specific types. 130/// per-module; then we build an index of all impl blocks in the crate. This
131/// way, we avoid having to do this process for the whole crate whenever someone
132/// types in any file; as long as the impl blocks in the file don't change, we
133/// don't need to do the second step again.
134///
135/// (The second step does not yet exist currently.)
131#[derive(Debug, PartialEq, Eq)] 136#[derive(Debug, PartialEq, Eq)]
132pub struct CrateImplBlocks { 137pub struct ModuleImplBlocks {
133 impls: Arena<ImplId, ImplData>, 138 impls: Arena<ImplId, ImplData>,
134 impls_by_def: FxHashMap<DefId, ImplId>, 139 impls_by_def: FxHashMap<DefId, ImplId>,
135} 140}
136 141
137impl CrateImplBlocks { 142impl ModuleImplBlocks {
138 fn new() -> Self { 143 fn new() -> Self {
139 CrateImplBlocks { 144 ModuleImplBlocks {
140 impls: Arena::default(), 145 impls: Arena::default(),
141 impls_by_def: FxHashMap::default(), 146 impls_by_def: FxHashMap::default(),
142 } 147 }
@@ -159,24 +164,17 @@ impl CrateImplBlocks {
159 } 164 }
160 } 165 }
161 166
162 for (_, child) in module.children() {
163 self.collect(db, child)?;
164 }
165
166 Ok(()) 167 Ok(())
167 } 168 }
168} 169}
169 170
170pub(crate) fn impls_in_crate( 171pub(crate) fn impls_in_module(
171 db: &impl HirDatabase, 172 db: &impl HirDatabase,
172 krate: Crate, 173 source_root_id: SourceRootId,
173) -> Cancelable<Arc<CrateImplBlocks>> { 174 module_id: ModuleId,
174 let mut result = CrateImplBlocks::new(); 175) -> Cancelable<Arc<ModuleImplBlocks>> {
175 let root_module = if let Some(root) = krate.root_module(db)? { 176 let mut result = ModuleImplBlocks::new();
176 root 177 let module = Module::new(db, source_root_id, module_id)?;
177 } else { 178 result.collect(db, module)?;
178 return Ok(Arc::new(result));
179 };
180 result.collect(db, root_module)?;
181 Ok(Arc::new(result)) 179 Ok(Arc::new(result))
182} 180}