Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/semantics.rs')
-rw-r--r--crates/hir/src/semantics.rs20
1 files changed, 18 insertions, 2 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 8427ca38be..a70dc5254c 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -132,6 +132,9 @@ pub struct SemanticsImpl<'db> {
s2d_cache: RefCell<SourceToDefCache>,
/// Rootnode to HirFileId cache
root_to_file_cache: RefCell<FxHashMap<SyntaxNode, HirFileId>>,
+ /// HirFileId to Rootnode cache (this adds a layer over the database LRU cache to prevent
+ /// possibly frequent invalidation)
+ parse_cache: RefCell<FxHashMap<HirFileId, SyntaxNode>>,
/// MacroCall to its expansion's MacroFileId cache
macro_call_cache: RefCell<FxHashMap<InFile<ast::MacroCall>, MacroFileId>>,
}
@@ -292,6 +295,7 @@ impl<'db> SemanticsImpl<'db> {
db,
s2d_cache: Default::default(),
root_to_file_cache: Default::default(),
+ parse_cache: Default::default(),
macro_call_cache: Default::default(),
}
}
@@ -303,6 +307,9 @@ impl<'db> SemanticsImpl<'db> {
}
pub fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode {
+ if let Some(root) = self.parse_cache.borrow().get(&file_id) {
+ return root.clone();
+ }
let node = self.db.parse_or_expand(file_id);
self.cache(node.clone(), file_id);
node
@@ -977,6 +984,13 @@ impl<'db> SemanticsImpl<'db> {
let helpers =
def_map.derive_helpers_in_scope(InFile::new(file_id, id))?;
+ if !helpers.is_empty() {
+ let text_range = attr.syntax().text_range();
+ // remove any other token in this macro input, all their mappings are the
+ // same as this
+ tokens.retain(|t| !text_range.contains_range(t.text_range()));
+ }
+
let mut res = None;
for (.., derive) in
helpers.iter().filter(|(helper, ..)| *helper == attr_name)
@@ -1407,6 +1421,7 @@ impl<'db> SemanticsImpl<'db> {
where
Def::Ast: AstNode,
{
+ // FIXME: source call should go through the parse cache
let res = def.source(self.db)?;
self.cache(find_root(res.value.syntax()), res.file_id);
Some(res)
@@ -1464,8 +1479,9 @@ impl<'db> SemanticsImpl<'db> {
fn cache(&self, root_node: SyntaxNode, file_id: HirFileId) {
assert!(root_node.parent().is_none());
let mut cache = self.root_to_file_cache.borrow_mut();
- let prev = cache.insert(root_node, file_id);
- assert!(prev.is_none() || prev == Some(file_id))
+ let prev = cache.insert(root_node.clone(), file_id);
+ assert!(prev.is_none() || prev == Some(file_id));
+ self.parse_cache.borrow_mut().insert(file_id, root_node);
}
pub fn assert_contains_node(&self, node: &SyntaxNode) {