diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index ad84eacfb3..094a4a7036 100644 --- a/crates/ide/src/expand_macro.rs +++ b/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()?; + 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(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); + + if !error.is_empty() { + expansion.insert_str(0, &format!("Expansion had errors:{error}\n\n")); } - 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); - - 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! + "<>""#]], ); }