about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir-def/src/macro_expansion_tests/mbe/matching.rs2
-rw-r--r--crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs2
-rw-r--r--crates/hir-def/src/macro_expansion_tests/mod.rs15
-rw-r--r--crates/hir-def/src/nameres/tests/incremental.rs4
-rw-r--r--crates/hir-expand/src/db.rs45
-rw-r--r--crates/hir-expand/src/hygiene.rs8
-rw-r--r--crates/hir-expand/src/lib.rs8
7 files changed, 56 insertions, 28 deletions
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs b/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs
index 26f16542cbb..b63d77b1b28 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs
@@ -33,7 +33,7 @@ m!(&k");
 "#,
         expect![[r#"
 macro_rules! m { ($i:literal) => {}; }
-/* error: Failed to lower macro args to token tree */"#]],
+/* error: invalid token tree */"#]],
     );
 }
 
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs b/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
index b8d2ca687c9..ae56934f632 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
@@ -98,7 +98,7 @@ macro_rules! m1 { ($x:ident) => { ($x } }
 macro_rules! m2 { ($x:ident) => {} }
 
 /* error: invalid macro definition: expected subtree */
-/* error: Failed to lower macro args to token tree */
+/* error: invalid token tree */
 "#]],
     )
 }
diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs
index 6286295c526..552d69ca2ea 100644
--- a/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -183,13 +183,14 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
         let range: Range<usize> = range.into();
 
         if show_token_ids {
-            let (tree, map, _) = &*arg;
-            let tt_range = call.token_tree().unwrap().syntax().text_range();
-            let mut ranges = Vec::new();
-            extract_id_ranges(&mut ranges, map, tree);
-            for (range, id) in ranges {
-                let idx = (tt_range.start() + range.end()).into();
-                text_edits.push((idx..idx, format!("#{}", id.0)));
+            if let Some((tree, map, _)) = arg.as_deref() {
+                let tt_range = call.token_tree().unwrap().syntax().text_range();
+                let mut ranges = Vec::new();
+                extract_id_ranges(&mut ranges, map, tree);
+                for (range, id) in ranges {
+                    let idx = (tt_range.start() + range.end()).into();
+                    text_edits.push((idx..idx, format!("#{}", id.0)));
+                }
             }
             text_edits.push((range.start..range.start, "// ".into()));
             call.to_string().match_indices('\n').for_each(|(offset, _)| {
diff --git a/crates/hir-def/src/nameres/tests/incremental.rs b/crates/hir-def/src/nameres/tests/incremental.rs
index b07462cde0f..d2e3575d5e8 100644
--- a/crates/hir-def/src/nameres/tests/incremental.rs
+++ b/crates/hir-def/src/nameres/tests/incremental.rs
@@ -109,7 +109,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() {
 }
 
 #[test]
-fn typing_inside_a_function_should_not_invalidate_expansions() {
+fn typing_inside_a_function_should_not_invalidate_item_expansions() {
     let (mut db, pos) = TestDB::with_position(
         r#"
 //- /lib.rs
@@ -161,7 +161,7 @@ m!(Z);
         let n_recalculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count();
         assert_eq!(n_recalculated_item_trees, 1);
         let n_reparsed_macros =
-            events.iter().filter(|it| it.contains("parse_macro_expansion")).count();
+            events.iter().filter(|it| it.contains("parse_macro_expansion(")).count();
         assert_eq!(n_reparsed_macros, 0);
     }
 }
diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs
index f7ee15375d7..bed04b3a343 100644
--- a/crates/hir-expand/src/db.rs
+++ b/crates/hir-expand/src/db.rs
@@ -120,7 +120,7 @@ pub trait ExpandDatabase: SourceDatabase {
     fn macro_arg(
         &self,
         id: MacroCallId,
-    ) -> Arc<(tt::Subtree, mbe::TokenMap, fixup::SyntaxFixupUndoInfo)>;
+    ) -> Option<Arc<(tt::Subtree, mbe::TokenMap, fixup::SyntaxFixupUndoInfo)>>;
     /// Extracts syntax node, corresponding to a macro call. That's a firewall
     /// query, only typing in the macro call itself changes the returned
     /// subtree.
@@ -318,17 +318,8 @@ fn parse_macro_expansion(
 fn macro_arg(
     db: &dyn ExpandDatabase,
     id: MacroCallId,
-) -> Arc<(tt::Subtree, mbe::TokenMap, fixup::SyntaxFixupUndoInfo)> {
-    let Some(arg) = db.macro_arg_text(id) else {
-        return Arc::new((
-            tt::Subtree {
-                delimiter: tt::Delimiter::UNSPECIFIED,
-                token_trees: Vec::new(),
-            },
-            Default::default(),
-            Default::default())
-        );
-    };
+) -> Option<Arc<(tt::Subtree, mbe::TokenMap, fixup::SyntaxFixupUndoInfo)>> {
+    let arg = db.macro_arg_text(id)?;
     let loc = db.lookup_intern_macro_call(id);
 
     let node = SyntaxNode::new_root(arg);
@@ -347,7 +338,7 @@ fn macro_arg(
         // proc macros expect their inputs without parentheses, MBEs expect it with them included
         tt.delimiter = tt::Delimiter::unspecified();
     }
-    Arc::new((tt, tmap, fixups.undo_info))
+    Some(Arc::new((tt, tmap, fixups.undo_info)))
 }
 
 fn censor_for_macro_input(loc: &MacroCallLoc, node: &SyntaxNode) -> FxHashSet<SyntaxNode> {
@@ -472,7 +463,20 @@ fn macro_expand(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt
             }
         }
     };
-    let macro_arg = db.macro_arg(id);
+    let Some(macro_arg) = db.macro_arg(id) else {
+        return ExpandResult {
+            value: Arc::new(
+                tt::Subtree {
+                    delimiter: tt::Delimiter::UNSPECIFIED,
+                    token_trees: Vec::new(),
+                },
+            ),
+            err: Some(ExpandError::Other(
+                "invalid token tree"
+                .into(),
+            )),
+        };
+    };
     let ExpandResult { value: mut tt, err } = expander.expand(db, id, &macro_arg.0);
     // Set a hard limit for the expanded tt
     let count = tt.count();
@@ -508,7 +512,18 @@ fn parse_macro_expansion_error(
 
 fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<tt::Subtree> {
     let loc: MacroCallLoc = db.lookup_intern_macro_call(id);
-    let macro_arg = db.macro_arg(id);
+    let Some(macro_arg) = db.macro_arg(id) else {
+        return ExpandResult {
+            value: tt::Subtree {
+                delimiter: tt::Delimiter::UNSPECIFIED,
+                token_trees: Vec::new(),
+            },
+            err: Some(ExpandError::Other(
+                "invalid token tree"
+                .into(),
+            )),
+        };
+    };
 
     let expander = match loc.def.kind {
         MacroDefKind::ProcMacro(expander, ..) => expander,
diff --git a/crates/hir-expand/src/hygiene.rs b/crates/hir-expand/src/hygiene.rs
index addffb88772..9af38fed044 100644
--- a/crates/hir-expand/src/hygiene.rs
+++ b/crates/hir-expand/src/hygiene.rs
@@ -201,7 +201,13 @@ fn make_hygiene_info(
 
     let macro_def = db.macro_def(loc.def).ok()?;
     let (_, exp_map) = db.parse_macro_expansion(macro_file).value;
-    let macro_arg = db.macro_arg(macro_file.macro_call_id);
+    let macro_arg = db.macro_arg(macro_file.macro_call_id).unwrap_or_else(|| {
+        Arc::new((
+            tt::Subtree { delimiter: tt::Delimiter::UNSPECIFIED, token_trees: Vec::new() },
+            Default::default(),
+            Default::default(),
+        ))
+    });
 
     Some(HygieneInfo {
         file: macro_file,
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index e442eea16e6..965b9e850b4 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -258,7 +258,13 @@ impl HirFileId {
 
         let macro_def = db.macro_def(loc.def).ok()?;
         let (parse, exp_map) = db.parse_macro_expansion(macro_file).value;
-        let macro_arg = db.macro_arg(macro_file.macro_call_id);
+        let macro_arg = db.macro_arg(macro_file.macro_call_id).unwrap_or_else(|| {
+            Arc::new((
+                tt::Subtree { delimiter: tt::Delimiter::UNSPECIFIED, token_trees: Vec::new() },
+                Default::default(),
+                Default::default(),
+            ))
+        });
 
         let def = loc.def.ast_id().left().and_then(|id| {
             let def_tt = match id.to_node(db) {