Skip to content

Commit 24cd443

Browse files
committed
Auto merge of #17225 - Veykril:expand-macro-interlocked, r=Veykril
Expand macro recursively expands both fp-like and attribute macros when intertwined
2 parents b0ecc29 + 5fa2b06 commit 24cd443

File tree

1 file changed

+15
-27
lines changed

1 file changed

+15
-27
lines changed

src/tools/rust-analyzer/crates/ide/src/expand_macro.rs

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
7676
return derive;
7777
}
7878

79-
// FIXME: Intermix attribute and bang! expansions
80-
// currently we only recursively expand one of the two types
8179
let mut anc = tok.parent_ancestors();
8280
let (name, expanded, kind) = loop {
8381
let node = anc.next()?;
@@ -86,19 +84,17 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
8684
if let Some(def) = sema.resolve_attr_macro_call(&item) {
8785
break (
8886
def.name(db).display(db).to_string(),
89-
expand_attr_macro_recur(&sema, &item)?,
87+
expand_macro_recur(&sema, &item)?,
9088
SyntaxKind::MACRO_ITEMS,
9189
);
9290
}
9391
}
9492
if let Some(mac) = ast::MacroCall::cast(node) {
9593
let mut name = mac.path()?.segment()?.name_ref()?.to_string();
9694
name.push('!');
97-
break (
98-
name,
99-
expand_macro_recur(&sema, &mac)?,
100-
mac.syntax().parent().map(|it| it.kind()).unwrap_or(SyntaxKind::MACRO_ITEMS),
101-
);
95+
let syntax_kind =
96+
mac.syntax().parent().map(|it| it.kind()).unwrap_or(SyntaxKind::MACRO_ITEMS);
97+
break (name, expand_macro_recur(&sema, &ast::Item::MacroCall(mac))?, syntax_kind);
10298
}
10399
};
104100

@@ -112,31 +108,23 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
112108

113109
fn expand_macro_recur(
114110
sema: &Semantics<'_, RootDatabase>,
115-
macro_call: &ast::MacroCall,
116-
) -> Option<SyntaxNode> {
117-
let expanded = sema.expand(macro_call)?.clone_for_update();
118-
expand(sema, expanded, ast::MacroCall::cast, expand_macro_recur)
119-
}
120-
121-
fn expand_attr_macro_recur(
122-
sema: &Semantics<'_, RootDatabase>,
123-
item: &ast::Item,
111+
macro_call: &ast::Item,
124112
) -> Option<SyntaxNode> {
125-
let expanded = sema.expand_attr_macro(item)?.clone_for_update();
126-
expand(sema, expanded, ast::Item::cast, expand_attr_macro_recur)
113+
let expanded = match macro_call {
114+
item @ ast::Item::MacroCall(macro_call) => {
115+
sema.expand_attr_macro(item).or_else(|| sema.expand(macro_call))?.clone_for_update()
116+
}
117+
item => sema.expand_attr_macro(item)?.clone_for_update(),
118+
};
119+
expand(sema, expanded)
127120
}
128121

129-
fn expand<T: AstNode>(
130-
sema: &Semantics<'_, RootDatabase>,
131-
expanded: SyntaxNode,
132-
f: impl FnMut(SyntaxNode) -> Option<T>,
133-
exp: impl Fn(&Semantics<'_, RootDatabase>, &T) -> Option<SyntaxNode>,
134-
) -> Option<SyntaxNode> {
135-
let children = expanded.descendants().filter_map(f);
122+
fn expand(sema: &Semantics<'_, RootDatabase>, expanded: SyntaxNode) -> Option<SyntaxNode> {
123+
let children = expanded.descendants().filter_map(ast::Item::cast);
136124
let mut replacements = Vec::new();
137125

138126
for child in children {
139-
if let Some(new_node) = exp(sema, &child) {
127+
if let Some(new_node) = expand_macro_recur(sema, &child) {
140128
// check if the whole original syntax is replaced
141129
if expanded == *child.syntax() {
142130
return Some(new_node);

0 commit comments

Comments
 (0)