Skip to content

Commit dd7f93e

Browse files
committed
Bring back EMPTY item tree deduplication
1 parent e1e7f59 commit dd7f93e

File tree

2 files changed

+37
-16
lines changed

2 files changed

+37
-16
lines changed

src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,10 @@ impl fmt::Debug for RawVisibilityId {
8686
}
8787
}
8888

89-
#[salsa_macros::tracked(returns(ref))]
90-
pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> ItemTree {
89+
#[salsa_macros::tracked(returns(deref))]
90+
pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
9191
let _p = tracing::info_span!("file_item_tree_query", ?file_id).entered();
92+
static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
9293

9394
let ctx = lower::Ctx::new(db, file_id);
9495
let syntax = db.parse_or_expand(file_id);
@@ -116,28 +117,49 @@ pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) ->
116117
},
117118
}
118119
};
119-
120-
item_tree.shrink_to_fit();
121-
item_tree
120+
let ItemTree { top_level, top_attrs, attrs, vis, big_data, small_data } = &item_tree;
121+
if small_data.is_empty()
122+
&& big_data.is_empty()
123+
&& top_level.is_empty()
124+
&& attrs.is_empty()
125+
&& top_attrs.is_empty()
126+
&& vis.arena.is_empty()
127+
{
128+
EMPTY
129+
.get_or_init(|| {
130+
Arc::new(ItemTree {
131+
top_level: Box::new([]),
132+
attrs: FxHashMap::default(),
133+
small_data: FxHashMap::default(),
134+
big_data: FxHashMap::default(),
135+
top_attrs: RawAttrs::EMPTY,
136+
vis: ItemVisibilities { arena: ThinVec::new() },
137+
})
138+
})
139+
.clone()
140+
} else {
141+
item_tree.shrink_to_fit();
142+
Arc::new(item_tree)
143+
}
122144
}
123145

124-
#[salsa_macros::tracked(returns(ref))]
146+
#[salsa_macros::tracked(returns(deref))]
125147
pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
126148
let _p = tracing::info_span!("block_item_tree_query", ?block).entered();
127-
// Blocks have a tendency to be empty due to macro calls that do not expand to items,
128-
// so deduplicate this case via `Arc` to reduce the size of the query storage here.
129149
static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
130150

131151
let loc = block.lookup(db);
132152
let block = loc.ast_id.to_node(db);
133153

134154
let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
135155
let mut item_tree = ctx.lower_block(&block);
136-
if item_tree.small_data.is_empty()
137-
&& item_tree.big_data.is_empty()
138-
&& item_tree.top_level.is_empty()
139-
&& item_tree.attrs.is_empty()
140-
&& item_tree.top_attrs.is_empty()
156+
let ItemTree { top_level, top_attrs, attrs, vis, big_data, small_data } = &item_tree;
157+
if small_data.is_empty()
158+
&& big_data.is_empty()
159+
&& top_level.is_empty()
160+
&& attrs.is_empty()
161+
&& top_attrs.is_empty()
162+
&& vis.arena.is_empty()
141163
{
142164
EMPTY
143165
.get_or_init(|| {
@@ -163,7 +185,6 @@ pub struct ItemTree {
163185
top_attrs: RawAttrs,
164186
attrs: FxHashMap<FileAstId<ast::Item>, RawAttrs>,
165187
vis: ItemVisibilities,
166-
// FIXME: They values store the key, turn this into a FxHashSet<ModItem> instead?
167188
big_data: FxHashMap<FileAstId<ast::Item>, BigModItem>,
168189
small_data: FxHashMap<FileAstId<ast::Item>, SmallModItem>,
169190
}

src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,8 +383,8 @@ impl<'a> Ctx<'a> {
383383
});
384384
match &vis {
385385
RawVisibility::Public => RawVisibilityId::PUB,
386-
RawVisibility::Module(path, explicitiy) if path.segments().is_empty() => {
387-
match (path.kind, explicitiy) {
386+
RawVisibility::Module(path, explicitness) if path.segments().is_empty() => {
387+
match (path.kind, explicitness) {
388388
(PathKind::SELF, VisibilityExplicitness::Explicit) => {
389389
RawVisibilityId::PRIV_EXPLICIT
390390
}

0 commit comments

Comments
 (0)