mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-29 10:58:02 +00:00
Bring back EMPTY item tree deduplication
This commit is contained in:
parent
c0258d01ba
commit
b9ce647cf1
2 changed files with 37 additions and 16 deletions
|
|
@ -86,9 +86,10 @@ impl fmt::Debug for RawVisibilityId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[salsa_macros::tracked(returns(ref))]
|
#[salsa_macros::tracked(returns(deref))]
|
||||||
pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> ItemTree {
|
pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
|
||||||
let _p = tracing::info_span!("file_item_tree_query", ?file_id).entered();
|
let _p = tracing::info_span!("file_item_tree_query", ?file_id).entered();
|
||||||
|
static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
|
||||||
|
|
||||||
let ctx = lower::Ctx::new(db, file_id);
|
let ctx = lower::Ctx::new(db, file_id);
|
||||||
let syntax = db.parse_or_expand(file_id);
|
let syntax = db.parse_or_expand(file_id);
|
||||||
|
|
@ -116,16 +117,35 @@ pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) ->
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let ItemTree { top_level, top_attrs, attrs, vis, big_data, small_data } = &item_tree;
|
||||||
item_tree.shrink_to_fit();
|
if small_data.is_empty()
|
||||||
item_tree
|
&& big_data.is_empty()
|
||||||
|
&& top_level.is_empty()
|
||||||
|
&& attrs.is_empty()
|
||||||
|
&& top_attrs.is_empty()
|
||||||
|
&& vis.arena.is_empty()
|
||||||
|
{
|
||||||
|
EMPTY
|
||||||
|
.get_or_init(|| {
|
||||||
|
Arc::new(ItemTree {
|
||||||
|
top_level: Box::new([]),
|
||||||
|
attrs: FxHashMap::default(),
|
||||||
|
small_data: FxHashMap::default(),
|
||||||
|
big_data: FxHashMap::default(),
|
||||||
|
top_attrs: RawAttrs::EMPTY,
|
||||||
|
vis: ItemVisibilities { arena: ThinVec::new() },
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.clone()
|
||||||
|
} else {
|
||||||
|
item_tree.shrink_to_fit();
|
||||||
|
Arc::new(item_tree)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[salsa_macros::tracked(returns(ref))]
|
#[salsa_macros::tracked(returns(deref))]
|
||||||
pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
|
pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
|
||||||
let _p = tracing::info_span!("block_item_tree_query", ?block).entered();
|
let _p = tracing::info_span!("block_item_tree_query", ?block).entered();
|
||||||
// Blocks have a tendency to be empty due to macro calls that do not expand to items,
|
|
||||||
// so deduplicate this case via `Arc` to reduce the size of the query storage here.
|
|
||||||
static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
|
static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
|
||||||
|
|
||||||
let loc = block.lookup(db);
|
let loc = block.lookup(db);
|
||||||
|
|
@ -133,11 +153,13 @@ pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc
|
||||||
|
|
||||||
let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
|
let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
|
||||||
let mut item_tree = ctx.lower_block(&block);
|
let mut item_tree = ctx.lower_block(&block);
|
||||||
if item_tree.small_data.is_empty()
|
let ItemTree { top_level, top_attrs, attrs, vis, big_data, small_data } = &item_tree;
|
||||||
&& item_tree.big_data.is_empty()
|
if small_data.is_empty()
|
||||||
&& item_tree.top_level.is_empty()
|
&& big_data.is_empty()
|
||||||
&& item_tree.attrs.is_empty()
|
&& top_level.is_empty()
|
||||||
&& item_tree.top_attrs.is_empty()
|
&& attrs.is_empty()
|
||||||
|
&& top_attrs.is_empty()
|
||||||
|
&& vis.arena.is_empty()
|
||||||
{
|
{
|
||||||
EMPTY
|
EMPTY
|
||||||
.get_or_init(|| {
|
.get_or_init(|| {
|
||||||
|
|
@ -163,7 +185,6 @@ pub struct ItemTree {
|
||||||
top_attrs: RawAttrs,
|
top_attrs: RawAttrs,
|
||||||
attrs: FxHashMap<FileAstId<ast::Item>, RawAttrs>,
|
attrs: FxHashMap<FileAstId<ast::Item>, RawAttrs>,
|
||||||
vis: ItemVisibilities,
|
vis: ItemVisibilities,
|
||||||
// FIXME: They values store the key, turn this into a FxHashSet<ModItem> instead?
|
|
||||||
big_data: FxHashMap<FileAstId<ast::Item>, BigModItem>,
|
big_data: FxHashMap<FileAstId<ast::Item>, BigModItem>,
|
||||||
small_data: FxHashMap<FileAstId<ast::Item>, SmallModItem>,
|
small_data: FxHashMap<FileAstId<ast::Item>, SmallModItem>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -383,8 +383,8 @@ impl<'a> Ctx<'a> {
|
||||||
});
|
});
|
||||||
match &vis {
|
match &vis {
|
||||||
RawVisibility::Public => RawVisibilityId::PUB,
|
RawVisibility::Public => RawVisibilityId::PUB,
|
||||||
RawVisibility::Module(path, explicitiy) if path.segments().is_empty() => {
|
RawVisibility::Module(path, explicitness) if path.segments().is_empty() => {
|
||||||
match (path.kind, explicitiy) {
|
match (path.kind, explicitness) {
|
||||||
(PathKind::SELF, VisibilityExplicitness::Explicit) => {
|
(PathKind::SELF, VisibilityExplicitness::Explicit) => {
|
||||||
RawVisibilityId::PRIV_EXPLICIT
|
RawVisibilityId::PRIV_EXPLICIT
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue