19
19
//!
20
20
//! See the full discussion : <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Eager.20expansion.20of.20built-in.20macros>
21
21
use base_db:: CrateId ;
22
- use rustc_hash:: FxHashMap ;
22
+ use rustc_hash:: { FxHashMap , FxHashSet } ;
23
23
use syntax:: { ted, Parse , SyntaxNode , TextRange , TextSize , WalkEvent } ;
24
24
use triomphe:: Arc ;
25
25
@@ -29,7 +29,7 @@ use crate::{
29
29
hygiene:: Hygiene ,
30
30
mod_path:: ModPath ,
31
31
EagerCallInfo , ExpandError , ExpandResult , ExpandTo , InFile , MacroCallId , MacroCallKind ,
32
- MacroCallLoc , MacroDefId , MacroDefKind , UnresolvedMacro ,
32
+ MacroCallLoc , MacroDefId , MacroDefKind ,
33
33
} ;
34
34
35
35
pub fn expand_eager_macro_input (
@@ -38,7 +38,7 @@ pub fn expand_eager_macro_input(
38
38
macro_call : InFile < ast:: MacroCall > ,
39
39
def : MacroDefId ,
40
40
resolver : & dyn Fn ( ModPath ) -> Option < MacroDefId > ,
41
- ) -> Result < ExpandResult < Option < MacroCallId > > , UnresolvedMacro > {
41
+ ) -> ExpandResult < Option < MacroCallId > > {
42
42
let ast_map = db. ast_id_map ( macro_call. file_id ) ;
43
43
// the expansion which the ast id map is built upon has no whitespace, so the offsets are wrong as macro_call is from the token tree that has whitespace!
44
44
let call_id = InFile :: new ( macro_call. file_id , ast_map. ast_id ( & macro_call. value ) ) ;
@@ -71,22 +71,23 @@ pub fn expand_eager_macro_input(
71
71
InFile :: new ( arg_id. as_file ( ) , arg_exp. syntax_node ( ) ) ,
72
72
krate,
73
73
resolver,
74
- ) ?
74
+ )
75
75
} ;
76
76
let err = parse_err. or ( err) ;
77
77
78
78
let Some ( ( expanded_eager_input, mapping) ) = expanded_eager_input else {
79
- return Ok ( ExpandResult { value : None , err } ) ;
79
+ return ExpandResult { value : None , err } ;
80
80
} ;
81
81
82
82
let ( mut subtree, expanded_eager_input_token_map) =
83
83
mbe:: syntax_node_to_token_tree ( & expanded_eager_input) ;
84
84
85
85
let og_tmap = if let Some ( tt) = macro_call. value . token_tree ( ) {
86
- let og_tmap = mbe:: syntax_node_to_token_map ( tt. syntax ( ) ) ;
86
+ let mut ids_used = FxHashSet :: default ( ) ;
87
+ let mut og_tmap = mbe:: syntax_node_to_token_map ( tt. syntax ( ) ) ;
87
88
// The tokenmap and ids of subtree point into the expanded syntax node, but that is inaccessible from the outside
88
89
// so we need to remap them to the original input of the eager macro.
89
- subtree. visit_ids ( & |id| {
90
+ subtree. visit_ids ( & mut |id| {
90
91
// Note: we discard all token ids of braces and the like here, but that's not too bad and only a temporary fix
91
92
92
93
if let Some ( range) = expanded_eager_input_token_map
@@ -97,13 +98,15 @@ pub fn expand_eager_macro_input(
97
98
// remap from eager input expansion to original eager input
98
99
if let Some ( & og_range) = ws_mapping. get ( og_range) {
99
100
if let Some ( og_token) = og_tmap. token_by_range ( og_range) {
101
+ ids_used. insert ( og_token) ;
100
102
return og_token;
101
103
}
102
104
}
103
105
}
104
106
}
105
107
tt:: TokenId :: UNSPECIFIED
106
108
} ) ;
109
+ og_tmap. filter ( |id| ids_used. contains ( & id) ) ;
107
110
og_tmap
108
111
} else {
109
112
Default :: default ( )
@@ -121,7 +124,7 @@ pub fn expand_eager_macro_input(
121
124
kind : MacroCallKind :: FnLike { ast_id : call_id, expand_to } ,
122
125
} ;
123
126
124
- Ok ( ExpandResult { value : Some ( db. intern_macro_call ( loc) ) , err } )
127
+ ExpandResult { value : Some ( db. intern_macro_call ( loc) ) , err }
125
128
}
126
129
127
130
fn lazy_expand (
@@ -147,13 +150,13 @@ fn eager_macro_recur(
147
150
curr : InFile < SyntaxNode > ,
148
151
krate : CrateId ,
149
152
macro_resolver : & dyn Fn ( ModPath ) -> Option < MacroDefId > ,
150
- ) -> Result < ExpandResult < Option < ( SyntaxNode , FxHashMap < TextRange , TextRange > ) > > , UnresolvedMacro > {
153
+ ) -> ExpandResult < Option < ( SyntaxNode , FxHashMap < TextRange , TextRange > ) > > {
151
154
let original = curr. value . clone_for_update ( ) ;
152
155
let mut mapping = FxHashMap :: default ( ) ;
153
156
154
157
let mut replacements = Vec :: new ( ) ;
155
158
156
- // Note : We only report a single error inside of eager expansions
159
+ // FIXME : We only report a single error inside of eager expansions
157
160
let mut error = None ;
158
161
let mut offset = 0i32 ;
159
162
let apply_offset = |it : TextSize , offset : i32 | {
@@ -184,24 +187,28 @@ fn eager_macro_recur(
184
187
}
185
188
} ;
186
189
let def = match call. path ( ) . and_then ( |path| ModPath :: from_src ( db, path, hygiene) ) {
187
- Some ( path) => macro_resolver ( path. clone ( ) ) . ok_or ( UnresolvedMacro { path } ) ?,
190
+ Some ( path) => match macro_resolver ( path. clone ( ) ) {
191
+ Some ( def) => def,
192
+ None => {
193
+ error =
194
+ Some ( ExpandError :: other ( format ! ( "unresolved macro {}" , path. display( db) ) ) ) ;
195
+ continue ;
196
+ }
197
+ } ,
188
198
None => {
189
199
error = Some ( ExpandError :: other ( "malformed macro invocation" ) ) ;
190
200
continue ;
191
201
}
192
202
} ;
193
203
let ExpandResult { value, err } = match def. kind {
194
204
MacroDefKind :: BuiltInEager ( ..) => {
195
- let ExpandResult { value, err } = match expand_eager_macro_input (
205
+ let ExpandResult { value, err } = expand_eager_macro_input (
196
206
db,
197
207
krate,
198
208
curr. with_value ( call. clone ( ) ) ,
199
209
def,
200
210
macro_resolver,
201
- ) {
202
- Ok ( it) => it,
203
- Err ( err) => return Err ( err) ,
204
- } ;
211
+ ) ;
205
212
match value {
206
213
Some ( call_id) => {
207
214
let ExpandResult { value, err : err2 } =
@@ -251,7 +258,7 @@ fn eager_macro_recur(
251
258
parse. as_ref ( ) . map ( |it| it. syntax_node ( ) ) ,
252
259
krate,
253
260
macro_resolver,
254
- ) ? ;
261
+ ) ;
255
262
let err = err. or ( error) ;
256
263
257
264
if let Some ( tt) = call. token_tree ( ) {
@@ -281,7 +288,7 @@ fn eager_macro_recur(
281
288
}
282
289
// check if the whole original syntax is replaced
283
290
if call. syntax ( ) == & original {
284
- return Ok ( ExpandResult { value : value. zip ( Some ( mapping) ) , err : error } ) ;
291
+ return ExpandResult { value : value. zip ( Some ( mapping) ) , err : error } ;
285
292
}
286
293
287
294
if let Some ( insert) = value {
@@ -292,5 +299,5 @@ fn eager_macro_recur(
292
299
}
293
300
294
301
replacements. into_iter ( ) . rev ( ) . for_each ( |( old, new) | ted:: replace ( old. syntax ( ) , new) ) ;
295
- Ok ( ExpandResult { value : Some ( ( original, mapping) ) , err : error } )
302
+ ExpandResult { value : Some ( ( original, mapping) ) , err : error }
296
303
}
0 commit comments