about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/expand_macro.rs95
1 files changed, 49 insertions, 46 deletions
diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
index ad84eacfb3e..094a4a7036c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
@@ -1,5 +1,5 @@
 use hir::db::ExpandDatabase;
-use hir::{ExpandResult, InFile, InRealFile, Semantics};
+use hir::{ExpandResult, InFile, Semantics};
 use ide_db::{
     FileId, RootDatabase, base_db::Crate, helpers::pick_best_token,
     syntax_helpers::prettify_macro_expansion,
@@ -87,52 +87,55 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
         return derive;
     }
 
-    let mut anc = sema
-        .descend_token_into_include_expansion(InRealFile::new(file_id, tok))
-        .value
-        .parent_ancestors();
-    let mut span_map = SpanMap::empty();
-    let mut error = String::new();
-    let (name, expanded, kind) = loop {
-        let node = anc.next()?;
-
-        if let Some(item) = ast::Item::cast(node.clone())
-            && let Some(def) = sema.resolve_attr_macro_call(&item)
-        {
-            break (
-                def.name(db).display(db, file_id.edition(db)).to_string(),
-                expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?,
-                SyntaxKind::MACRO_ITEMS,
-            );
-        }
-        if let Some(mac) = ast::MacroCall::cast(node) {
-            let mut name = mac.path()?.segment()?.name_ref()?.to_string();
-            name.push('!');
-            let syntax_kind =
-                mac.syntax().parent().map(|it| it.kind()).unwrap_or(SyntaxKind::MACRO_ITEMS);
-            break (
-                name,
-                expand_macro_recur(
-                    &sema,
-                    &ast::Item::MacroCall(mac),
-                    &mut error,
-                    &mut span_map,
-                    TextSize::new(0),
-                )?,
-                syntax_kind,
-            );
-        }
-    };
+    let syntax_token = sema.descend_into_macros_exact(tok);
+    'tokens: for syntax_token in syntax_token {
+        let mut anc = syntax_token.parent_ancestors();
+        let mut span_map = SpanMap::empty();
+        let mut error = String::new();
+        let (name, expanded, kind) = loop {
+            let Some(node) = anc.next() else {
+                continue 'tokens;
+            };
+
+            if let Some(item) = ast::Item::cast(node.clone())
+                && let Some(def) = sema.resolve_attr_macro_call(&item)
+            {
+                break (
+                    def.name(db).display(db, file_id.edition(db)).to_string(),
+                    expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?,
+                    SyntaxKind::MACRO_ITEMS,
+                );
+            }
+            if let Some(mac) = ast::MacroCall::cast(node) {
+                let mut name = mac.path()?.segment()?.name_ref()?.to_string();
+                name.push('!');
+                let syntax_kind =
+                    mac.syntax().parent().map(|it| it.kind()).unwrap_or(SyntaxKind::MACRO_ITEMS);
+                break (
+                    name,
+                    expand_macro_recur(
+                        &sema,
+                        &ast::Item::MacroCall(mac),
+                        &mut error,
+                        &mut span_map,
+                        TextSize::new(0),
+                    )?,
+                    syntax_kind,
+                );
+            }
+        };
 
-    // FIXME:
-    // macro expansion may lose all white space information
-    // But we hope someday we can use ra_fmt for that
-    let mut expansion = format(db, kind, position.file_id, expanded, &span_map, krate);
+        // FIXME:
+        // macro expansion may lose all white space information
+        // But we hope someday we can use ra_fmt for that
+        let mut expansion = format(db, kind, position.file_id, expanded, &span_map, krate);
 
-    if !error.is_empty() {
-        expansion.insert_str(0, &format!("Expansion had errors:{error}\n\n"));
+        if !error.is_empty() {
+            expansion.insert_str(0, &format!("Expansion had errors:{error}\n\n"));
+        }
+        return Some(ExpandedMacro { name, expansion });
     }
-    Some(ExpandedMacro { name, expansion })
+    None
 }
 
 fn expand_macro_recur(
@@ -752,8 +755,8 @@ fn test() {
 }
     "#,
             expect![[r#"
-                my_concat!
-                "<>hi""#]],
+                concat!
+                "<>""#]],
         );
     }