Skip to content

Commit 57ad00b

Browse files
authored
Merge pull request #20612 from Veykril/veykril/push-vzuykrsxvrts
fix: Fix expand macro recursively not working correctly for nested macro calls
2 parents 0bbc55b + bd57ea0 commit 57ad00b

File tree

1 file changed

+49
-46
lines changed

1 file changed

+49
-46
lines changed

crates/ide/src/expand_macro.rs

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use hir::db::ExpandDatabase;
2-
use hir::{ExpandResult, InFile, InRealFile, Semantics};
2+
use hir::{ExpandResult, InFile, Semantics};
33
use ide_db::{
44
FileId, RootDatabase, base_db::Crate, helpers::pick_best_token,
55
syntax_helpers::prettify_macro_expansion,
@@ -87,52 +87,55 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
8787
return derive;
8888
}
8989

90-
let mut anc = sema
91-
.descend_token_into_include_expansion(InRealFile::new(file_id, tok))
92-
.value
93-
.parent_ancestors();
94-
let mut span_map = SpanMap::empty();
95-
let mut error = String::new();
96-
let (name, expanded, kind) = loop {
97-
let node = anc.next()?;
98-
99-
if let Some(item) = ast::Item::cast(node.clone())
100-
&& let Some(def) = sema.resolve_attr_macro_call(&item)
101-
{
102-
break (
103-
def.name(db).display(db, file_id.edition(db)).to_string(),
104-
expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?,
105-
SyntaxKind::MACRO_ITEMS,
106-
);
107-
}
108-
if let Some(mac) = ast::MacroCall::cast(node) {
109-
let mut name = mac.path()?.segment()?.name_ref()?.to_string();
110-
name.push('!');
111-
let syntax_kind =
112-
mac.syntax().parent().map(|it| it.kind()).unwrap_or(SyntaxKind::MACRO_ITEMS);
113-
break (
114-
name,
115-
expand_macro_recur(
116-
&sema,
117-
&ast::Item::MacroCall(mac),
118-
&mut error,
119-
&mut span_map,
120-
TextSize::new(0),
121-
)?,
122-
syntax_kind,
123-
);
124-
}
125-
};
90+
let syntax_token = sema.descend_into_macros_exact(tok);
91+
'tokens: for syntax_token in syntax_token {
92+
let mut anc = syntax_token.parent_ancestors();
93+
let mut span_map = SpanMap::empty();
94+
let mut error = String::new();
95+
let (name, expanded, kind) = loop {
96+
let Some(node) = anc.next() else {
97+
continue 'tokens;
98+
};
99+
100+
if let Some(item) = ast::Item::cast(node.clone())
101+
&& let Some(def) = sema.resolve_attr_macro_call(&item)
102+
{
103+
break (
104+
def.name(db).display(db, file_id.edition(db)).to_string(),
105+
expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?,
106+
SyntaxKind::MACRO_ITEMS,
107+
);
108+
}
109+
if let Some(mac) = ast::MacroCall::cast(node) {
110+
let mut name = mac.path()?.segment()?.name_ref()?.to_string();
111+
name.push('!');
112+
let syntax_kind =
113+
mac.syntax().parent().map(|it| it.kind()).unwrap_or(SyntaxKind::MACRO_ITEMS);
114+
break (
115+
name,
116+
expand_macro_recur(
117+
&sema,
118+
&ast::Item::MacroCall(mac),
119+
&mut error,
120+
&mut span_map,
121+
TextSize::new(0),
122+
)?,
123+
syntax_kind,
124+
);
125+
}
126+
};
126127

127-
// FIXME:
128-
// macro expansion may lose all white space information
129-
// But we hope someday we can use ra_fmt for that
130-
let mut expansion = format(db, kind, position.file_id, expanded, &span_map, krate);
128+
// FIXME:
129+
// macro expansion may lose all white space information
130+
// But we hope someday we can use ra_fmt for that
131+
let mut expansion = format(db, kind, position.file_id, expanded, &span_map, krate);
131132

132-
if !error.is_empty() {
133-
expansion.insert_str(0, &format!("Expansion had errors:{error}\n\n"));
133+
if !error.is_empty() {
134+
expansion.insert_str(0, &format!("Expansion had errors:{error}\n\n"));
135+
}
136+
return Some(ExpandedMacro { name, expansion });
134137
}
135-
Some(ExpandedMacro { name, expansion })
138+
None
136139
}
137140

138141
fn expand_macro_recur(
@@ -752,8 +755,8 @@ fn test() {
752755
}
753756
"#,
754757
expect![[r#"
755-
my_concat!
756-
"<>hi""#]],
758+
concat!
759+
"<>""#]],
757760
);
758761
}
759762

0 commit comments

Comments
 (0)