diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/db.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 52 |
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}; | |||
4 | use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable}; | 4 | use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable}; |
5 | 5 | ||
6 | use crate::{ | 6 | use 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 | ||
19 | salsa::query_group! { | 19 | salsa::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 | ||
4 | use ra_arena::{Arena, RawId, impl_arena_id}; | 4 | use ra_arena::{Arena, RawId, impl_arena_id}; |
5 | use ra_syntax::ast::{self, AstNode}; | 5 | use ra_syntax::ast::{self, AstNode}; |
6 | use ra_db::{LocationIntener, Cancelable}; | 6 | use ra_db::{LocationIntener, Cancelable, SourceRootId}; |
7 | 7 | ||
8 | use crate::{ | 8 | use 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)] |
17 | pub struct ImplBlock { | 17 | pub 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 | ||
22 | impl ImplBlock { | 22 | impl 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 { | |||
126 | pub struct ImplId(pub RawId); | 126 | pub struct ImplId(pub RawId); |
127 | impl_arena_id!(ImplId); | 127 | impl_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)] |
132 | pub struct CrateImplBlocks { | 137 | pub 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 | ||
137 | impl CrateImplBlocks { | 142 | impl 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 | ||
170 | pub(crate) fn impls_in_crate( | 171 | pub(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 | } |