@@ -76,6 +76,55 @@ impl<'a> Iterator for Frame<'a> {
76
76
}
77
77
}
78
78
79
+ fn mark_tt ( tt : & mut mbe:: TokenTree , marker : & mut Marker ) {
80
+ // Spans that never end up in the output don't need to be marked.
81
+ // `_ident`s are metavariable names and need to keep their original spans to resolve correctly
82
+ // (they also never end up in the output).
83
+ match tt {
84
+ mbe:: TokenTree :: Token ( token) => mut_visit:: visit_token ( token, marker) ,
85
+ mbe:: TokenTree :: Delimited ( dspan, _dspacing, delimited) => {
86
+ mut_visit:: visit_delim_span ( dspan, marker) ;
87
+ mark_delimited ( delimited, marker) ;
88
+ }
89
+ mbe:: TokenTree :: Sequence ( _dspan, rep) => {
90
+ // Sequence delimiter spans never ends up in the output.
91
+ mark_sequence_repetition ( rep, marker) ;
92
+ }
93
+ mbe:: TokenTree :: MetaVar ( span, _ident, marked_span) => {
94
+ marker. visit_span ( span) ;
95
+ marker. visit_span ( marked_span) ;
96
+ }
97
+ mbe:: TokenTree :: MetaVarExpr ( dspan, expr) => {
98
+ mut_visit:: visit_delim_span ( dspan, marker) ;
99
+ match expr {
100
+ MetaVarExpr :: Count ( _ident, _depth) => { }
101
+ MetaVarExpr :: Ignore ( _ident) => { }
102
+ MetaVarExpr :: Index ( _depth) | MetaVarExpr :: Length ( _depth) => { }
103
+ }
104
+ }
105
+ mbe:: TokenTree :: MetaVarDecl ( ..) => unreachable ! ( ) ,
106
+ }
107
+ }
108
+
109
+ fn mark_sequence_repetition ( rep : & mut mbe:: SequenceRepetition , marker : & mut Marker ) {
110
+ let mbe:: SequenceRepetition { tts, separator, kleene, num_captures : _ } = rep;
111
+ for tt in tts {
112
+ mark_tt ( tt, marker) ;
113
+ }
114
+ if let Some ( sep) = separator {
115
+ mut_visit:: visit_token ( sep, marker) ;
116
+ }
117
+ // Kleenee token span never ends up in the output.
118
+ let mbe:: KleeneToken { span : _, op : _ } = kleene;
119
+ }
120
+
121
+ fn mark_delimited ( delimited : & mut mbe:: Delimited , marker : & mut Marker ) {
122
+ let mbe:: Delimited { delim : _, tts } = delimited;
123
+ for tt in tts {
124
+ mark_tt ( tt, marker) ;
125
+ }
126
+ }
127
+
79
128
/// This can do Macro-By-Example transcription.
80
129
/// - `interp` is a map of meta-variables to the tokens (non-terminals) they matched in the
81
130
/// invocation. We are assuming we already know there is a match.
@@ -108,11 +157,15 @@ pub(super) fn transcribe<'a>(
108
157
return Ok ( TokenStream :: default ( ) ) ;
109
158
}
110
159
160
+ let mut src = src. clone ( ) ;
161
+ let expn_id = cx. current_expansion . id ;
162
+ mark_delimited ( & mut src, & mut Marker ( expn_id, transparency, Default :: default ( ) ) ) ;
163
+
111
164
// We descend into the RHS (`src`), expanding things as we go. This stack contains the things
112
165
// we have yet to expand/are still expanding. We start the stack off with the whole RHS. The
113
166
// choice of spacing values doesn't matter.
114
167
let mut stack: SmallVec < [ Frame < ' _ > ; 1 ] > =
115
- smallvec ! [ Frame :: new( src, src_span, DelimSpacing :: new( Spacing :: Alone , Spacing :: Alone ) ) ] ;
168
+ smallvec ! [ Frame :: new( & src, src_span, DelimSpacing :: new( Spacing :: Alone , Spacing :: Alone ) ) ] ;
116
169
117
170
// As we descend in the RHS, we will need to be able to match nested sequences of matchers.
118
171
// `repeats` keeps track of where we are in matching at each level, with the last element being
@@ -132,7 +185,6 @@ pub(super) fn transcribe<'a>(
132
185
// again, and we are done transcribing.
133
186
let mut result: Vec < TokenTree > = Vec :: new ( ) ;
134
187
let mut result_stack = Vec :: new ( ) ;
135
- let mut marker = Marker ( cx. current_expansion . id , transparency, Default :: default ( ) ) ;
136
188
137
189
loop {
138
190
// Look at the last frame on the stack.
@@ -245,10 +297,11 @@ pub(super) fn transcribe<'a>(
245
297
}
246
298
247
299
// Replace the meta-var with the matched token tree from the invocation.
248
- mbe:: TokenTree :: MetaVar ( mut sp, mut original_ident) => {
300
+ mbe:: TokenTree :: MetaVar ( sp, original_ident, marked_span) => {
301
+ let sp = * sp;
249
302
// Find the matched nonterminal from the macro invocation, and use it to replace
250
303
// the meta-var.
251
- let ident = MacroRulesNormalizedIdent :: new ( original_ident) ;
304
+ let ident = MacroRulesNormalizedIdent :: new ( * original_ident) ;
252
305
if let Some ( cur_matched) = lookup_cur_matched ( ident, interp, & repeats) {
253
306
match cur_matched {
254
307
MatchedTokenTree ( tt) => {
@@ -260,7 +313,6 @@ pub(super) fn transcribe<'a>(
260
313
// Other variables are emitted into the output stream as groups with
261
314
// `Delimiter::Invisible` to maintain parsing priorities.
262
315
// `Interpolated` is currently used for such groups in rustc parser.
263
- marker. visit_span ( & mut sp) ;
264
316
result
265
317
. push ( TokenTree :: token_alone ( token:: Interpolated ( nt. clone ( ) ) , sp) ) ;
266
318
}
@@ -272,33 +324,30 @@ pub(super) fn transcribe<'a>(
272
324
} else {
273
325
// If we aren't able to match the meta-var, we push it back into the result but
274
326
// with modified syntax context. (I believe this supports nested macros).
275
- marker. visit_span ( & mut sp) ;
276
- marker. visit_ident ( & mut original_ident) ;
277
327
result. push ( TokenTree :: token_joint_hidden ( token:: Dollar , sp) ) ;
278
328
result. push ( TokenTree :: Token (
279
- Token :: from_ast_ident ( original_ident) ,
329
+ Token :: from_ast_ident ( Ident :: new ( original_ident. name , * marked_span ) ) ,
280
330
Spacing :: Alone ,
281
331
) ) ;
282
332
}
283
333
}
284
334
285
335
// Replace meta-variable expressions with the result of their expansion.
286
336
mbe:: TokenTree :: MetaVarExpr ( sp, expr) => {
287
- transcribe_metavar_expr ( cx, expr, interp, & mut marker , & repeats, & mut result, sp) ?;
337
+ transcribe_metavar_expr ( cx, expr, interp, & repeats, & mut result, sp) ?;
288
338
}
289
339
290
340
// If we are entering a new delimiter, we push its contents to the `stack` to be
291
341
// processed, and we push all of the currently produced results to the `result_stack`.
292
342
// We will produce all of the results of the inside of the `Delimited` and then we will
293
343
// jump back out of the Delimited, pop the result_stack and add the new results back to
294
344
// the previous results (from outside the Delimited).
295
- mbe:: TokenTree :: Delimited ( mut span, spacing, delimited) => {
296
- mut_visit:: visit_delim_span ( & mut span, & mut marker) ;
345
+ mbe:: TokenTree :: Delimited ( span, spacing, delimited) => {
297
346
stack. push ( Frame :: Delimited {
298
347
tts : & delimited. tts ,
299
348
delim : delimited. delim ,
300
349
idx : 0 ,
301
- span,
350
+ span : * span ,
302
351
spacing : * spacing,
303
352
} ) ;
304
353
result_stack. push ( mem:: take ( & mut result) ) ;
@@ -307,10 +356,7 @@ pub(super) fn transcribe<'a>(
307
356
// Nothing much to do here. Just push the token to the result, being careful to
308
357
// preserve syntax context.
309
358
mbe:: TokenTree :: Token ( token) => {
310
- let mut token = token. clone ( ) ;
311
- mut_visit:: visit_token ( & mut token, & mut marker) ;
312
- let tt = TokenTree :: Token ( token, Spacing :: Alone ) ;
313
- result. push ( tt) ;
359
+ result. push ( TokenTree :: Token ( token. clone ( ) , Spacing :: Alone ) ) ;
314
360
}
315
361
316
362
// There should be no meta-var declarations in the invocation of a macro.
@@ -475,7 +521,7 @@ fn lockstep_iter_size(
475
521
size. with ( lockstep_iter_size ( tt, interpolations, repeats) )
476
522
} )
477
523
}
478
- TokenTree :: MetaVar ( _, name) | TokenTree :: MetaVarDecl ( _, name, _) => {
524
+ TokenTree :: MetaVar ( _, name, _ ) | TokenTree :: MetaVarDecl ( _, name, _) => {
479
525
let name = MacroRulesNormalizedIdent :: new ( * name) ;
480
526
match lookup_cur_matched ( name, interpolations, repeats) {
481
527
Some ( matched) => match matched {
@@ -620,23 +666,17 @@ fn transcribe_metavar_expr<'a>(
620
666
cx : & ExtCtxt < ' a > ,
621
667
expr : & MetaVarExpr ,
622
668
interp : & FxHashMap < MacroRulesNormalizedIdent , NamedMatch > ,
623
- marker : & mut Marker ,
624
669
repeats : & [ ( usize , usize ) ] ,
625
670
result : & mut Vec < TokenTree > ,
626
671
sp : & DelimSpan ,
627
672
) -> PResult < ' a , ( ) > {
628
- let mut visited_span = || {
629
- let mut span = sp. entire ( ) ;
630
- marker. visit_span ( & mut span) ;
631
- span
632
- } ;
633
673
match * expr {
634
674
MetaVarExpr :: Count ( original_ident, depth) => {
635
675
let matched = matched_from_ident ( cx, original_ident, interp) ?;
636
676
let count = count_repetitions ( cx, depth, matched, repeats, sp) ?;
637
677
let tt = TokenTree :: token_alone (
638
678
TokenKind :: lit ( token:: Integer , sym:: integer ( count) , None ) ,
639
- visited_span ( ) ,
679
+ sp . entire ( ) ,
640
680
) ;
641
681
result. push ( tt) ;
642
682
}
@@ -648,7 +688,7 @@ fn transcribe_metavar_expr<'a>(
648
688
Some ( ( index, _) ) => {
649
689
result. push ( TokenTree :: token_alone (
650
690
TokenKind :: lit ( token:: Integer , sym:: integer ( * index) , None ) ,
651
- visited_span ( ) ,
691
+ sp . entire ( ) ,
652
692
) ) ;
653
693
}
654
694
None => return Err ( out_of_bounds_err ( cx, repeats. len ( ) , sp. entire ( ) , "index" ) ) ,
@@ -657,7 +697,7 @@ fn transcribe_metavar_expr<'a>(
657
697
Some ( ( _, length) ) => {
658
698
result. push ( TokenTree :: token_alone (
659
699
TokenKind :: lit ( token:: Integer , sym:: integer ( * length) , None ) ,
660
- visited_span ( ) ,
700
+ sp . entire ( ) ,
661
701
) ) ;
662
702
}
663
703
None => return Err ( out_of_bounds_err ( cx, repeats. len ( ) , sp. entire ( ) , "length" ) ) ,
0 commit comments