about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-11-05 13:26:56 +0000
committerGitHub <noreply@github.com>2021-11-05 13:26:56 +0000
commitd1e449e313555a36fae31302f0fce5812ed84e9b (patch)
tree6dc09ee4e168902704f58220b2fb32a0d20ea647
parent10782bbb39485d0c0f42ff80d72233a42c4c67bb (diff)
parentaf4d244462c17540ce91af6d42ccbd1b50ad756d (diff)
downloadrust-d1e449e313555a36fae31302f0fce5812ed84e9b.tar.gz
rust-d1e449e313555a36fae31302f0fce5812ed84e9b.zip
Merge #10701
10701: internal: Cache ast::MacroCalls to their expansions in Semantics::descend_into_macros_impl r=Veykril a=Veykril

Saves ~45ms when highlighting `rust-analyzer/src/config.rs` for me
bors r+

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
-rw-r--r--crates/hir/src/semantics.rs27
1 files changed, 18 insertions, 9 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 4f481613dd8..1acad1ae396 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -121,7 +121,10 @@ pub struct SemanticsImpl<'db> {
     pub db: &'db dyn HirDatabase,
     s2d_cache: RefCell<SourceToDefCache>,
     expansion_info_cache: RefCell<FxHashMap<HirFileId, Option<ExpansionInfo>>>,
+    // Rootnode to HirFileId cache
     cache: RefCell<FxHashMap<SyntaxNode, HirFileId>>,
+    // MacroCall to its expansion's HirFileId cache
+    macro_call_cache: RefCell<FxHashMap<InFile<ast::MacroCall>, HirFileId>>,
 }
 
 impl<DB> fmt::Debug for Semantics<'_, DB> {
@@ -396,6 +399,7 @@ impl<'db> SemanticsImpl<'db> {
             s2d_cache: Default::default(),
             cache: Default::default(),
             expansion_info_cache: Default::default(),
+            macro_call_cache: Default::default(),
         }
     }
 
@@ -554,6 +558,7 @@ impl<'db> SemanticsImpl<'db> {
         let sa = self.analyze(&parent);
         let mut stack: SmallVec<[_; 1]> = smallvec![InFile::new(sa.file_id, token)];
         let mut cache = self.expansion_info_cache.borrow_mut();
+        let mut mcache = self.macro_call_cache.borrow_mut();
 
         let mut process_expansion_for_token =
             |stack: &mut SmallVec<_>, file_id, item, token: InFile<&_>| {
@@ -582,14 +587,10 @@ impl<'db> SemanticsImpl<'db> {
             let was_not_remapped = (|| {
                 // are we inside an attribute macro call
                 let containing_attribute_macro_call = self.with_ctx(|ctx| {
-                    token
-                        .value
-                        .ancestors()
-                        .filter_map(ast::Item::cast)
-                        .filter_map(|item| {
-                            Some((ctx.item_to_macro_call(token.with_value(item.clone()))?, item))
-                        })
-                        .last()
+                    token.value.ancestors().filter_map(ast::Item::cast).find_map(|item| {
+                        // investigate this, seems to be VERY(250ms) expensive in rust-analyzer/src/config.rs?
+                        Some((ctx.item_to_macro_call(token.with_value(item.clone()))?, item))
+                    })
                 });
                 if let Some((call_id, item)) = containing_attribute_macro_call {
                     let file_id = call_id.as_file();
@@ -616,7 +617,15 @@ impl<'db> SemanticsImpl<'db> {
                         return None;
                     }
 
-                    let file_id = sa.expand(self.db, token.with_value(&macro_call))?;
+                    let mcall = token.with_value(macro_call);
+                    let file_id = match mcache.get(&mcall) {
+                        Some(&it) => it,
+                        None => {
+                            let it = sa.expand(self.db, mcall.as_ref())?;
+                            mcache.insert(mcall, it);
+                            it
+                        }
+                    };
                     return process_expansion_for_token(&mut stack, file_id, None, token.as_ref());
                 }