diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 6d5235ba466..a045bbb12ef 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -4,7 +4,7 @@ use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable}; use crate::{ - Crate, DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId, + DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId, SourceFileItems, SourceItemId, query_definitions, FnScopes, @@ -13,7 +13,7 @@ nameres::{ItemMap, InputModuleItems}}, ty::{InferenceResult, Ty}, adt::{StructData, EnumData}, - impl_block::CrateImplBlocks, + impl_block::ModuleImplBlocks, }; salsa::query_group! { @@ -89,9 +89,9 @@ fn module_tree(source_root_id: SourceRootId) -> Cancelable> { use fn crate::module::imp::module_tree; } - fn impls_in_crate(krate: Crate) -> Cancelable> { + fn impls_in_module(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable> { type ImplsInCrateQuery; - use fn crate::impl_block::impls_in_crate; + use fn crate::impl_block::impls_in_module; } } diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index c98be66f92f..4d6378e0286 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs @@ -185,8 +185,9 @@ pub fn krate(&self, db: &impl HirDatabase) -> Cancelable> { /// Returns the containing impl block, if this is an impl item. pub fn impl_block(self, db: &impl HirDatabase) -> Cancelable> { - let crate_impls = db.impls_in_crate(ctry!(self.krate(db)?))?; - Ok(ImplBlock::containing(crate_impls, self)) + let loc = self.loc(db); + let module_impls = db.impls_in_module(loc.source_root_id, loc.module_id)?; + Ok(ImplBlock::containing(module_impls, self)) } } diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 77fab24d069..01afa84c496 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs @@ -3,36 +3,36 @@ use ra_arena::{Arena, RawId, impl_arena_id}; use ra_syntax::ast::{self, AstNode}; -use ra_db::{LocationIntener, Cancelable}; +use ra_db::{LocationIntener, Cancelable, SourceRootId}; use crate::{ - Crate, DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, + DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, Module, Function, db::HirDatabase, type_ref::TypeRef, - module::{ModuleSourceNode}, + module::{ModuleSourceNode, ModuleId}, }; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ImplBlock { - crate_impl_blocks: Arc, + module_impl_blocks: Arc, impl_id: ImplId, } impl ImplBlock { pub(crate) fn containing( - crate_impl_blocks: Arc, + module_impl_blocks: Arc, def_id: DefId, ) -> Option { - let impl_id = *crate_impl_blocks.impls_by_def.get(&def_id)?; + let impl_id = *module_impl_blocks.impls_by_def.get(&def_id)?; Some(ImplBlock { - crate_impl_blocks, + module_impl_blocks, impl_id, }) } fn impl_data(&self) -> &ImplData { - &self.crate_impl_blocks.impls[self.impl_id] + &self.module_impl_blocks.impls[self.impl_id] } pub fn target_trait(&self) -> Option<&TypeRef> { @@ -126,17 +126,22 @@ pub fn def_id(&self) -> DefId { pub struct ImplId(pub RawId); impl_arena_id!(ImplId); -/// We have to collect all impl blocks in a crate, to later be able to find -/// impls for specific types. +/// Collection of impl blocks is a two-step process: First we collect the blocks +/// per-module; then we build an index of all impl blocks in the crate. This +/// way, we avoid having to do this process for the whole crate whenever someone +/// types in any file; as long as the impl blocks in the file don't change, we +/// don't need to do the second step again. +/// +/// (The second step does not yet exist currently.) #[derive(Debug, PartialEq, Eq)] -pub struct CrateImplBlocks { +pub struct ModuleImplBlocks { impls: Arena, impls_by_def: FxHashMap, } -impl CrateImplBlocks { +impl ModuleImplBlocks { fn new() -> Self { - CrateImplBlocks { + ModuleImplBlocks { impls: Arena::default(), impls_by_def: FxHashMap::default(), } @@ -159,24 +164,17 @@ fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { } } - for (_, child) in module.children() { - self.collect(db, child)?; - } - Ok(()) } } -pub(crate) fn impls_in_crate( +pub(crate) fn impls_in_module( db: &impl HirDatabase, - krate: Crate, -) -> Cancelable> { - let mut result = CrateImplBlocks::new(); - let root_module = if let Some(root) = krate.root_module(db)? { - root - } else { - return Ok(Arc::new(result)); - }; - result.collect(db, root_module)?; + source_root_id: SourceRootId, + module_id: ModuleId, +) -> Cancelable> { + let mut result = ModuleImplBlocks::new(); + let module = Module::new(db, source_root_id, module_id)?; + result.collect(db, module)?; Ok(Arc::new(result)) }