about summary refs log tree commit diff
path: root/src/tools
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-06-04 15:21:22 +0200
committerLukas Wirth <lukastw97@gmail.com>2024-06-04 15:29:24 +0200
commit8d5e14d408d3287bbbb3af970fa4ea72f91fdd04 (patch)
tree2e0376df9bbde73115548e3f1d40b505b9b94a7e /src/tools
parentc5a5c93ed9293d44882a4e1976f610e03363f4ce (diff)
downloadrust-8d5e14d408d3287bbbb3af970fa4ea72f91fdd04.tar.gz
rust-8d5e14d408d3287bbbb3af970fa4ea72f91fdd04.zip
Cache parse trees in `Semantics`
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/lib.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs20
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs1
3 files changed, 22 insertions, 4 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
index 131625a96aa..a586b543c84 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
@@ -411,7 +411,7 @@ impl MacroFileIdExt for MacroFileId {
     fn is_attr_macro(&self, db: &dyn ExpandDatabase) -> bool {
         matches!(
             db.lookup_intern_macro_call(self.macro_call_id).def.kind,
-            MacroDefKind::BuiltInAttr(..) | MacroDefKind::ProcMacro(_, ProcMacroKind::Attr, _)
+            MacroDefKind::BuiltInAttr(..) | MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr)
         )
     }
 
@@ -721,7 +721,7 @@ impl ExpansionInfo {
     pub fn is_attr(&self) -> bool {
         matches!(
             self.loc.def.kind,
-            MacroDefKind::BuiltInAttr(..) | MacroDefKind::ProcMacro(_, ProcMacroKind::Attr, _)
+            MacroDefKind::BuiltInAttr(..) | MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr)
         )
     }
 
@@ -809,6 +809,7 @@ impl ExpansionInfo {
     }
 
     pub fn new(db: &dyn ExpandDatabase, macro_file: MacroFileId) -> ExpansionInfo {
+        let _p = tracing::span!(tracing::Level::INFO, "ExpansionInfo::new").entered();
         let loc = db.lookup_intern_macro_call(macro_file.macro_call_id);
 
         let arg_tt = loc.kind.arg(db);
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index 8427ca38be6..a70dc5254c7 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/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) {
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
index de24b7d2016..85e7c31ddf9 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
@@ -405,6 +405,7 @@ impl SourceToDefCtx<'_, '_> {
     }
 
     pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> {
+        let _p = tracing::span!(tracing::Level::INFO, "find_container").entered();
         let def =
             self.ancestors_with_macros(src, |this, container| this.container_to_def(container));
         if let Some(def) = def {