From 443ddb73c395a311b4ddff3bd8267a0eb7079216 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 4 Jan 2019 19:29:53 +0100 Subject: Do impl collection per module, not per crate --- crates/ra_hir/src/db.rs | 8 +++---- crates/ra_hir/src/ids.rs | 5 ++-- 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}; 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 @@ use crate::{ nameres::{ItemMap, InputModuleItems}}, ty::{InferenceResult, Ty}, adt::{StructData, EnumData}, - impl_block::CrateImplBlocks, + impl_block::ModuleImplBlocks, }; salsa::query_group! { @@ -89,9 +89,9 @@ pub trait HirDatabase: SyntaxDatabase 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 c98be66f9..4d6378e02 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs @@ -185,8 +185,9 @@ impl DefId { /// 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 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; 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 @@ impl ImplItem { 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 @@ impl CrateImplBlocks { } } - 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)) } -- cgit v1.2.3