@@ -76,8 +76,6 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
76
76
return derive;
77
77
}
78
78
79
- // FIXME: Intermix attribute and bang! expansions
80
- // currently we only recursively expand one of the two types
81
79
let mut anc = tok. parent_ancestors ( ) ;
82
80
let ( name, expanded, kind) = loop {
83
81
let node = anc. next ( ) ?;
@@ -86,19 +84,17 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
86
84
if let Some ( def) = sema. resolve_attr_macro_call ( & item) {
87
85
break (
88
86
def. name ( db) . display ( db) . to_string ( ) ,
89
- expand_attr_macro_recur ( & sema, & item) ?,
87
+ expand_macro_recur ( & sema, & item) ?,
90
88
SyntaxKind :: MACRO_ITEMS ,
91
89
) ;
92
90
}
93
91
}
94
92
if let Some ( mac) = ast:: MacroCall :: cast ( node) {
95
93
let mut name = mac. path ( ) ?. segment ( ) ?. name_ref ( ) ?. to_string ( ) ;
96
94
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) ;
102
98
}
103
99
} ;
104
100
@@ -112,31 +108,23 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
112
108
113
109
fn expand_macro_recur (
114
110
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 ,
124
112
) -> 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)
127
120
}
128
121
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) ;
136
124
let mut replacements = Vec :: new ( ) ;
137
125
138
126
for child in children {
139
- if let Some ( new_node) = exp ( sema, & child) {
127
+ if let Some ( new_node) = expand_macro_recur ( sema, & child) {
140
128
// check if the whole original syntax is replaced
141
129
if expanded == * child. syntax ( ) {
142
130
return Some ( new_node) ;
0 commit comments