Skip to content

Commit d32b09d

Browse files
committed
fix: Fix semantics not always correctly caching file roots
1 parent d82e1a2 commit d32b09d

File tree

2 files changed

+36
-40
lines changed

2 files changed

+36
-40
lines changed

crates/hir/src/semantics.rs

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,6 @@ pub struct Semantics<'db, DB> {
136136
pub struct SemanticsImpl<'db> {
137137
pub db: &'db dyn HirDatabase,
138138
s2d_cache: RefCell<SourceToDefCache>,
139-
/// Rootnode to HirFileId cache
140-
root_to_file_cache: RefCell<FxHashMap<SyntaxNode, HirFileId>>,
141139
/// MacroCall to its expansion's MacroFileId cache
142140
macro_call_cache: RefCell<FxHashMap<InFile<ast::MacroCall>, MacroFileId>>,
143141
}
@@ -304,12 +302,7 @@ impl<DB: HirDatabase> Semantics<'_, DB> {
304302

305303
impl<'db> SemanticsImpl<'db> {
306304
fn new(db: &'db dyn HirDatabase) -> Self {
307-
SemanticsImpl {
308-
db,
309-
s2d_cache: Default::default(),
310-
root_to_file_cache: Default::default(),
311-
macro_call_cache: Default::default(),
312-
}
305+
SemanticsImpl { db, s2d_cache: Default::default(), macro_call_cache: Default::default() }
313306
}
314307

315308
pub fn parse(&self, file_id: EditionedFileId) -> ast::SourceFile {
@@ -483,7 +476,7 @@ impl<'db> SemanticsImpl<'db> {
483476
Some(
484477
calls
485478
.into_iter()
486-
.map(|call| macro_call_to_macro_id(self, ctx, call?).map(|id| Macro { id }))
479+
.map(|call| macro_call_to_macro_id(ctx, call?).map(|id| Macro { id }))
487480
.collect(),
488481
)
489482
})
@@ -962,7 +955,7 @@ impl<'db> SemanticsImpl<'db> {
962955
let InMacroFile { file_id, value: mapped_tokens } = self.with_ctx(|ctx| {
963956
Some(
964957
ctx.cache
965-
.get_or_insert_expansion(self, macro_file)
958+
.get_or_insert_expansion(ctx.db, macro_file)
966959
.map_range_down(span)?
967960
.map(SmallVec::<[_; 2]>::from_iter),
968961
)
@@ -1287,7 +1280,7 @@ impl<'db> SemanticsImpl<'db> {
12871280
let macro_file = file_id.macro_file()?;
12881281

12891282
self.with_ctx(|ctx| {
1290-
let expansion_info = ctx.cache.get_or_insert_expansion(self, macro_file);
1283+
let expansion_info = ctx.cache.get_or_insert_expansion(ctx.db, macro_file);
12911284
expansion_info.arg().map(|node| node?.parent()).transpose()
12921285
})
12931286
}
@@ -1318,8 +1311,8 @@ impl<'db> SemanticsImpl<'db> {
13181311
}
13191312

13201313
pub fn resolve_label(&self, label: &ast::Lifetime) -> Option<Label> {
1321-
let (parent, label_id) = self
1322-
.with_ctx(|ctx| ctx.label_ref_to_def(self.wrap_node_infile(label.clone()).as_ref()))?;
1314+
let src = self.wrap_node_infile(label.clone());
1315+
let (parent, label_id) = self.with_ctx(|ctx| ctx.label_ref_to_def(src.as_ref()))?;
13231316
Some(Label { parent, label_id })
13241317
}
13251318

@@ -1519,7 +1512,7 @@ impl<'db> SemanticsImpl<'db> {
15191512
let macro_call = self.find_file(macro_call.syntax()).with_value(macro_call);
15201513
self.with_ctx(|ctx| {
15211514
ctx.macro_call_to_macro_call(macro_call)
1522-
.and_then(|call| macro_call_to_macro_id(self, ctx, call))
1515+
.and_then(|call| macro_call_to_macro_id(ctx, call))
15231516
.map(Into::into)
15241517
})
15251518
.or_else(|| {
@@ -1561,7 +1554,7 @@ impl<'db> SemanticsImpl<'db> {
15611554
let item_in_file = self.wrap_node_infile(item.clone());
15621555
let id = self.with_ctx(|ctx| {
15631556
let macro_call_id = ctx.item_to_macro_call(item_in_file.as_ref())?;
1564-
macro_call_to_macro_id(self, ctx, macro_call_id)
1557+
macro_call_to_macro_id(ctx, macro_call_id)
15651558
})?;
15661559
Some(Macro { id })
15671560
}
@@ -1725,19 +1718,20 @@ impl<'db> SemanticsImpl<'db> {
17251718
}
17261719

17271720
fn cache(&self, root_node: SyntaxNode, file_id: HirFileId) {
1728-
assert!(root_node.parent().is_none());
1729-
let mut cache = self.root_to_file_cache.borrow_mut();
1730-
let prev = cache.insert(root_node, file_id);
1731-
assert!(prev.is_none() || prev == Some(file_id));
1721+
SourceToDefCache::cache(
1722+
&mut self.s2d_cache.borrow_mut().root_to_file_cache,
1723+
root_node,
1724+
file_id,
1725+
);
17321726
}
17331727

17341728
pub fn assert_contains_node(&self, node: &SyntaxNode) {
17351729
self.find_file(node);
17361730
}
17371731

17381732
fn lookup(&self, root_node: &SyntaxNode) -> Option<HirFileId> {
1739-
let cache = self.root_to_file_cache.borrow();
1740-
cache.get(root_node).copied()
1733+
let cache = self.s2d_cache.borrow();
1734+
cache.root_to_file_cache.get(root_node).copied()
17411735
}
17421736

17431737
fn wrap_node_infile<N: AstNode>(&self, node: N) -> InFile<N> {
@@ -1761,8 +1755,9 @@ impl<'db> SemanticsImpl<'db> {
17611755
known nodes: {}\n\n",
17621756
node,
17631757
root_node,
1764-
self.root_to_file_cache
1758+
self.s2d_cache
17651759
.borrow()
1760+
.root_to_file_cache
17661761
.keys()
17671762
.map(|it| format!("{it:?}"))
17681763
.collect::<Vec<_>>()
@@ -1909,7 +1904,6 @@ impl<'db> SemanticsImpl<'db> {
19091904
}
19101905

19111906
fn macro_call_to_macro_id(
1912-
sema: &SemanticsImpl<'_>,
19131907
ctx: &mut SourceToDefCtx<'_, '_>,
19141908
macro_call_id: MacroCallId,
19151909
) -> Option<MacroId> {
@@ -1925,7 +1919,7 @@ fn macro_call_to_macro_id(
19251919
it.to_ptr(db).to_node(&db.parse(file_id).syntax_node())
19261920
}
19271921
HirFileIdRepr::MacroFile(macro_file) => {
1928-
let expansion_info = ctx.cache.get_or_insert_expansion(sema, macro_file);
1922+
let expansion_info = ctx.cache.get_or_insert_expansion(ctx.db, macro_file);
19291923
it.to_ptr(db).to_node(&expansion_info.expanded().value)
19301924
}
19311925
};
@@ -1937,7 +1931,7 @@ fn macro_call_to_macro_id(
19371931
it.to_ptr(db).to_node(&db.parse(file_id).syntax_node())
19381932
}
19391933
HirFileIdRepr::MacroFile(macro_file) => {
1940-
let expansion_info = ctx.cache.get_or_insert_expansion(sema, macro_file);
1934+
let expansion_info = ctx.cache.get_or_insert_expansion(ctx.db, macro_file);
19411935
it.to_ptr(db).to_node(&expansion_info.expanded().value)
19421936
}
19431937
};

crates/hir/src/semantics/source_to_def.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -110,20 +110,29 @@ use syntax::{
110110
AstNode, AstPtr, SyntaxNode,
111111
};
112112

113-
use crate::{
114-
db::HirDatabase, semantics::child_by_source::ChildBySource, InFile, InlineAsmOperand,
115-
SemanticsImpl,
116-
};
113+
use crate::{db::HirDatabase, semantics::child_by_source::ChildBySource, InFile, InlineAsmOperand};
117114

118115
#[derive(Default)]
119116
pub(super) struct SourceToDefCache {
120117
pub(super) dynmap_cache: FxHashMap<(ChildContainer, HirFileId), DynMap>,
121118
expansion_info_cache: FxHashMap<MacroFileId, ExpansionInfo>,
122119
pub(super) file_to_def_cache: FxHashMap<FileId, SmallVec<[ModuleId; 1]>>,
123120
pub(super) included_file_cache: FxHashMap<EditionedFileId, Option<MacroFileId>>,
121+
/// Rootnode to HirFileId cache
122+
pub(super) root_to_file_cache: FxHashMap<SyntaxNode, HirFileId>,
124123
}
125124

126125
impl SourceToDefCache {
126+
pub(super) fn cache(
127+
root_to_file_cache: &mut FxHashMap<SyntaxNode, HirFileId>,
128+
root_node: SyntaxNode,
129+
file_id: HirFileId,
130+
) {
131+
assert!(root_node.parent().is_none());
132+
let prev = root_to_file_cache.insert(root_node, file_id);
133+
assert!(prev.is_none() || prev == Some(file_id));
134+
}
135+
127136
pub(super) fn get_or_insert_include_for(
128137
&mut self,
129138
db: &dyn HirDatabase,
@@ -143,14 +152,14 @@ impl SourceToDefCache {
143152

144153
pub(super) fn get_or_insert_expansion(
145154
&mut self,
146-
sema: &SemanticsImpl<'_>,
155+
db: &dyn HirDatabase,
147156
macro_file: MacroFileId,
148157
) -> &ExpansionInfo {
149158
self.expansion_info_cache.entry(macro_file).or_insert_with(|| {
150-
let exp_info = macro_file.expansion_info(sema.db.upcast());
159+
let exp_info = macro_file.expansion_info(db.upcast());
151160

152161
let InMacroFile { file_id, value } = exp_info.expanded();
153-
sema.cache(value, file_id.into());
162+
Self::cache(&mut self.root_to_file_cache, value, file_id.into());
154163

155164
exp_info
156165
})
@@ -520,18 +529,11 @@ impl SourceToDefCtx<'_, '_> {
520529
node: InFile<&SyntaxNode>,
521530
mut cb: impl FnMut(&mut Self, InFile<SyntaxNode>) -> Option<T>,
522531
) -> Option<T> {
523-
use hir_expand::MacroFileIdExt;
524532
let parent = |this: &mut Self, node: InFile<&SyntaxNode>| match node.value.parent() {
525533
Some(parent) => Some(node.with_value(parent)),
526534
None => {
527535
let macro_file = node.file_id.macro_file()?;
528-
529-
let expansion_info = this
530-
.cache
531-
.expansion_info_cache
532-
.entry(macro_file)
533-
.or_insert_with(|| macro_file.expansion_info(this.db.upcast()));
534-
536+
let expansion_info = this.cache.get_or_insert_expansion(this.db, macro_file);
535537
expansion_info.arg().map(|node| node?.parent()).transpose()
536538
}
537539
};

0 commit comments

Comments
 (0)