Do impl collection per module, not per crate
This commit is contained in:
parent
334ca0d9a7
commit
443ddb73c3
@ -4,7 +4,7 @@ use ra_syntax::{SyntaxNode, SourceFileNode};
|
|||||||
use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable};
|
use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Crate, DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId,
|
DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId,
|
||||||
SourceFileItems, SourceItemId,
|
SourceFileItems, SourceItemId,
|
||||||
query_definitions,
|
query_definitions,
|
||||||
FnScopes,
|
FnScopes,
|
||||||
@ -13,7 +13,7 @@ use crate::{
|
|||||||
nameres::{ItemMap, InputModuleItems}},
|
nameres::{ItemMap, InputModuleItems}},
|
||||||
ty::{InferenceResult, Ty},
|
ty::{InferenceResult, Ty},
|
||||||
adt::{StructData, EnumData},
|
adt::{StructData, EnumData},
|
||||||
impl_block::CrateImplBlocks,
|
impl_block::ModuleImplBlocks,
|
||||||
};
|
};
|
||||||
|
|
||||||
salsa::query_group! {
|
salsa::query_group! {
|
||||||
@ -89,9 +89,9 @@ pub trait HirDatabase: SyntaxDatabase
|
|||||||
use fn crate::module::imp::module_tree;
|
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;
|
type ImplsInCrateQuery;
|
||||||
use fn crate::impl_block::impls_in_crate;
|
use fn crate::impl_block::impls_in_module;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,8 +185,9 @@ impl DefId {
|
|||||||
|
|
||||||
/// Returns the containing impl block, if this is an impl item.
|
/// Returns the containing impl block, if this is an impl item.
|
||||||
pub fn impl_block(self, db: &impl HirDatabase) -> Cancelable<Option<ImplBlock>> {
|
pub fn impl_block(self, db: &impl HirDatabase) -> Cancelable<Option<ImplBlock>> {
|
||||||
let crate_impls = db.impls_in_crate(ctry!(self.krate(db)?))?;
|
let loc = self.loc(db);
|
||||||
Ok(ImplBlock::containing(crate_impls, self))
|
let module_impls = db.impls_in_module(loc.source_root_id, loc.module_id)?;
|
||||||
|
Ok(ImplBlock::containing(module_impls, self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,36 +3,36 @@ use rustc_hash::FxHashMap;
|
|||||||
|
|
||||||
use ra_arena::{Arena, RawId, impl_arena_id};
|
use ra_arena::{Arena, RawId, impl_arena_id};
|
||||||
use ra_syntax::ast::{self, AstNode};
|
use ra_syntax::ast::{self, AstNode};
|
||||||
use ra_db::{LocationIntener, Cancelable};
|
use ra_db::{LocationIntener, Cancelable, SourceRootId};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Crate, DefId, DefLoc, DefKind, SourceItemId, SourceFileItems,
|
DefId, DefLoc, DefKind, SourceItemId, SourceFileItems,
|
||||||
Module, Function,
|
Module, Function,
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
type_ref::TypeRef,
|
type_ref::TypeRef,
|
||||||
module::{ModuleSourceNode},
|
module::{ModuleSourceNode, ModuleId},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ImplBlock {
|
pub struct ImplBlock {
|
||||||
crate_impl_blocks: Arc<CrateImplBlocks>,
|
module_impl_blocks: Arc<ModuleImplBlocks>,
|
||||||
impl_id: ImplId,
|
impl_id: ImplId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImplBlock {
|
impl ImplBlock {
|
||||||
pub(crate) fn containing(
|
pub(crate) fn containing(
|
||||||
crate_impl_blocks: Arc<CrateImplBlocks>,
|
module_impl_blocks: Arc<ModuleImplBlocks>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> Option<ImplBlock> {
|
) -> 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 {
|
Some(ImplBlock {
|
||||||
crate_impl_blocks,
|
module_impl_blocks,
|
||||||
impl_id,
|
impl_id,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn impl_data(&self) -> &ImplData {
|
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> {
|
pub fn target_trait(&self) -> Option<&TypeRef> {
|
||||||
@ -126,17 +126,22 @@ impl ImplItem {
|
|||||||
pub struct ImplId(pub RawId);
|
pub struct ImplId(pub RawId);
|
||||||
impl_arena_id!(ImplId);
|
impl_arena_id!(ImplId);
|
||||||
|
|
||||||
/// We have to collect all impl blocks in a crate, to later be able to find
|
/// Collection of impl blocks is a two-step process: First we collect the blocks
|
||||||
/// impls for specific types.
|
/// 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)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct CrateImplBlocks {
|
pub struct ModuleImplBlocks {
|
||||||
impls: Arena<ImplId, ImplData>,
|
impls: Arena<ImplId, ImplData>,
|
||||||
impls_by_def: FxHashMap<DefId, ImplId>,
|
impls_by_def: FxHashMap<DefId, ImplId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CrateImplBlocks {
|
impl ModuleImplBlocks {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
CrateImplBlocks {
|
ModuleImplBlocks {
|
||||||
impls: Arena::default(),
|
impls: Arena::default(),
|
||||||
impls_by_def: FxHashMap::default(),
|
impls_by_def: FxHashMap::default(),
|
||||||
}
|
}
|
||||||
@ -159,24 +164,17 @@ impl CrateImplBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (_, child) in module.children() {
|
|
||||||
self.collect(db, child)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn impls_in_crate(
|
pub(crate) fn impls_in_module(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
krate: Crate,
|
source_root_id: SourceRootId,
|
||||||
) -> Cancelable<Arc<CrateImplBlocks>> {
|
module_id: ModuleId,
|
||||||
let mut result = CrateImplBlocks::new();
|
) -> Cancelable<Arc<ModuleImplBlocks>> {
|
||||||
let root_module = if let Some(root) = krate.root_module(db)? {
|
let mut result = ModuleImplBlocks::new();
|
||||||
root
|
let module = Module::new(db, source_root_id, module_id)?;
|
||||||
} else {
|
result.collect(db, module)?;
|
||||||
return Ok(Arc::new(result));
|
|
||||||
};
|
|
||||||
result.collect(db, root_module)?;
|
|
||||||
Ok(Arc::new(result))
|
Ok(Arc::new(result))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user