]> git.lizzy.rs Git - rust.git/commitdiff
Do impl collection per module, not per crate
authorFlorian Diebold <flodiebold@gmail.com>
Fri, 4 Jan 2019 18:29:53 +0000 (19:29 +0100)
committerFlorian Diebold <flodiebold@gmail.com>
Fri, 4 Jan 2019 18:29:53 +0000 (19:29 +0100)
crates/ra_hir/src/db.rs
crates/ra_hir/src/ids.rs
crates/ra_hir/src/impl_block.rs

index 6d5235ba46652e88b2a40191a4f7e6946b696961..a045bbb12ef3ae9fea9f765930f99ae27e3670df 100644 (file)
@@ -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<Arc<ModuleTree>> {
         use fn crate::module::imp::module_tree;
     }
 
-    fn impls_in_crate(krate: Crate) -> Cancelable<Arc<CrateImplBlocks>> {
+    fn impls_in_module(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<ModuleImplBlocks>> {
         type ImplsInCrateQuery;
-        use fn crate::impl_block::impls_in_crate;
+        use fn crate::impl_block::impls_in_module;
     }
 }
 
index c98be66f92fa0e0c64b2e01a31a8150c6f63ea40..4d6378e0286353d3c817b985edb27642ea44bd0f 100644 (file)
@@ -185,8 +185,9 @@ pub fn krate(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> {
 
     /// Returns the containing impl block, if this is an impl item.
     pub fn impl_block(self, db: &impl HirDatabase) -> Cancelable<Option<ImplBlock>> {
-        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))
     }
 }
 
index 77fab24d0691ff4caa3b96f2ae8e284d98d36f8c..01afa84c4964f74be15e513414c3cda543fde873 100644 (file)
@@ -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<CrateImplBlocks>,
+    module_impl_blocks: Arc<ModuleImplBlocks>,
     impl_id: ImplId,
 }
 
 impl ImplBlock {
     pub(crate) fn containing(
-        crate_impl_blocks: Arc<CrateImplBlocks>,
+        module_impl_blocks: Arc<ModuleImplBlocks>,
         def_id: DefId,
     ) -> Option<ImplBlock> {
-        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<ImplId, ImplData>,
     impls_by_def: FxHashMap<DefId, ImplId>,
 }
 
-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<Arc<CrateImplBlocks>> {
-    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<Arc<ModuleImplBlocks>> {
+    let mut result = ModuleImplBlocks::new();
+    let module = Module::new(db, source_root_id, module_id)?;
+    result.collect(db, module)?;
     Ok(Arc::new(result))
 }