@@ -67,6 +67,55 @@ impl<'a> Iterator for Frame<'a> {
67
67
}
68
68
}
69
69
70
+ fn mark_tt ( tt : & mut mbe:: TokenTree , marker : & mut Marker ) {
71
+ // Spans that never end up in the output don't need to be marked.
72
+ // `_ident`s are metavariable names and need to keep their original spans to resolve correctly
73
+ // (they also never end up in the output).
74
+ match tt {
75
+ mbe:: TokenTree :: Token ( token) => mut_visit:: visit_token ( token, marker) ,
76
+ mbe:: TokenTree :: Delimited ( dspan, _dspacing, delimited) => {
77
+ mut_visit:: visit_delim_span ( dspan, marker) ;
78
+ mark_delimited ( delimited, marker) ;
79
+ }
80
+ mbe:: TokenTree :: Sequence ( _dspan, rep) => {
81
+ // Sequence delimiter spans never ends up in the output.
82
+ mark_sequence_repetition ( rep, marker) ;
83
+ }
84
+ mbe:: TokenTree :: MetaVar ( span, _ident, marked_span) => {
85
+ marker. visit_span ( span) ;
86
+ marker. visit_span ( marked_span) ;
87
+ }
88
+ mbe:: TokenTree :: MetaVarExpr ( dspan, expr) => {
89
+ mut_visit:: visit_delim_span ( dspan, marker) ;
90
+ match expr {
91
+ MetaVarExpr :: Count ( _ident, _depth) => { }
92
+ MetaVarExpr :: Ignore ( _ident) => { }
93
+ MetaVarExpr :: Index ( _depth) | MetaVarExpr :: Length ( _depth) => { }
94
+ }
95
+ }
96
+ mbe:: TokenTree :: MetaVarDecl ( ..) => unreachable ! ( ) ,
97
+ }
98
+ }
99
+
100
+ fn mark_sequence_repetition ( rep : & mut mbe:: SequenceRepetition , marker : & mut Marker ) {
101
+ let mbe:: SequenceRepetition { tts, separator, kleene, num_captures : _ } = rep;
102
+ for tt in tts {
103
+ mark_tt ( tt, marker) ;
104
+ }
105
+ if let Some ( sep) = separator {
106
+ mut_visit:: visit_token ( sep, marker) ;
107
+ }
108
+ // Kleenee token span never ends up in the output.
109
+ let mbe:: KleeneToken { span : _, op : _ } = kleene;
110
+ }
111
+
112
+ fn mark_delimited ( delimited : & mut mbe:: Delimited , marker : & mut Marker ) {
113
+ let mbe:: Delimited { delim : _, tts } = delimited;
114
+ for tt in tts {
115
+ mark_tt ( tt, marker) ;
116
+ }
117
+ }
118
+
70
119
/// This can do Macro-By-Example transcription.
71
120
/// - `interp` is a map of meta-variables to the tokens (non-terminals) they matched in the
72
121
/// invocation. We are assuming we already know there is a match.
@@ -99,11 +148,14 @@ pub(super) fn transcribe<'a>(
99
148
return Ok ( TokenStream :: default ( ) ) ;
100
149
}
101
150
151
+ let mut src = src. clone ( ) ;
152
+ mark_delimited ( & mut src, & mut Marker ( cx. current_expansion . id , transparency) ) ;
153
+
102
154
// We descend into the RHS (`src`), expanding things as we go. This stack contains the things
103
155
// we have yet to expand/are still expanding. We start the stack off with the whole RHS. The
104
156
// choice of spacing values doesn't matter.
105
157
let mut stack: SmallVec < [ Frame < ' _ > ; 1 ] > =
106
- smallvec ! [ Frame :: new( src, src_span, DelimSpacing :: new( Spacing :: Alone , Spacing :: Alone ) ) ] ;
158
+ smallvec ! [ Frame :: new( & src, src_span, DelimSpacing :: new( Spacing :: Alone , Spacing :: Alone ) ) ] ;
107
159
108
160
// As we descend in the RHS, we will need to be able to match nested sequences of matchers.
109
161
// `repeats` keeps track of where we are in matching at each level, with the last element being
@@ -123,7 +175,6 @@ pub(super) fn transcribe<'a>(
123
175
// again, and we are done transcribing.
124
176
let mut result: Vec < TokenTree > = Vec :: new ( ) ;
125
177
let mut result_stack = Vec :: new ( ) ;
126
- let mut marker = Marker ( cx. current_expansion . id , transparency) ;
127
178
128
179
loop {
129
180
// Look at the last frame on the stack.
@@ -236,10 +287,11 @@ pub(super) fn transcribe<'a>(
236
287
}
237
288
238
289
// Replace the meta-var with the matched token tree from the invocation.
239
- mbe:: TokenTree :: MetaVar ( mut sp, mut original_ident) => {
290
+ mbe:: TokenTree :: MetaVar ( sp, original_ident, marked_span) => {
291
+ let sp = * sp;
240
292
// Find the matched nonterminal from the macro invocation, and use it to replace
241
293
// the meta-var.
242
- let ident = MacroRulesNormalizedIdent :: new ( original_ident) ;
294
+ let ident = MacroRulesNormalizedIdent :: new ( * original_ident) ;
243
295
if let Some ( cur_matched) = lookup_cur_matched ( ident, interp, & repeats) {
244
296
match cur_matched {
245
297
MatchedTokenTree ( tt) => {
@@ -251,7 +303,6 @@ pub(super) fn transcribe<'a>(
251
303
// Other variables are emitted into the output stream as groups with
252
304
// `Delimiter::Invisible` to maintain parsing priorities.
253
305
// `Interpolated` is currently used for such groups in rustc parser.
254
- marker. visit_span ( & mut sp) ;
255
306
result
256
307
. push ( TokenTree :: token_alone ( token:: Interpolated ( nt. clone ( ) ) , sp) ) ;
257
308
}
@@ -263,33 +314,30 @@ pub(super) fn transcribe<'a>(
263
314
} else {
264
315
// If we aren't able to match the meta-var, we push it back into the result but
265
316
// with modified syntax context. (I believe this supports nested macros).
266
- marker. visit_span ( & mut sp) ;
267
- marker. visit_ident ( & mut original_ident) ;
268
317
result. push ( TokenTree :: token_joint_hidden ( token:: Dollar , sp) ) ;
269
318
result. push ( TokenTree :: Token (
270
- Token :: from_ast_ident ( original_ident) ,
319
+ Token :: from_ast_ident ( Ident :: new ( original_ident. name , * marked_span ) ) ,
271
320
Spacing :: Alone ,
272
321
) ) ;
273
322
}
274
323
}
275
324
276
325
// Replace meta-variable expressions with the result of their expansion.
277
326
mbe:: TokenTree :: MetaVarExpr ( sp, expr) => {
278
- transcribe_metavar_expr ( cx, expr, interp, & mut marker , & repeats, & mut result, sp) ?;
327
+ transcribe_metavar_expr ( cx, expr, interp, & repeats, & mut result, sp) ?;
279
328
}
280
329
281
330
// If we are entering a new delimiter, we push its contents to the `stack` to be
282
331
// processed, and we push all of the currently produced results to the `result_stack`.
283
332
// We will produce all of the results of the inside of the `Delimited` and then we will
284
333
// jump back out of the Delimited, pop the result_stack and add the new results back to
285
334
// the previous results (from outside the Delimited).
286
- mbe:: TokenTree :: Delimited ( mut span, spacing, delimited) => {
287
- mut_visit:: visit_delim_span ( & mut span, & mut marker) ;
335
+ mbe:: TokenTree :: Delimited ( span, spacing, delimited) => {
288
336
stack. push ( Frame :: Delimited {
289
337
tts : & delimited. tts ,
290
338
delim : delimited. delim ,
291
339
idx : 0 ,
292
- span,
340
+ span : * span ,
293
341
spacing : * spacing,
294
342
} ) ;
295
343
result_stack. push ( mem:: take ( & mut result) ) ;
@@ -298,10 +346,7 @@ pub(super) fn transcribe<'a>(
298
346
// Nothing much to do here. Just push the token to the result, being careful to
299
347
// preserve syntax context.
300
348
mbe:: TokenTree :: Token ( token) => {
301
- let mut token = token. clone ( ) ;
302
- mut_visit:: visit_token ( & mut token, & mut marker) ;
303
- let tt = TokenTree :: Token ( token, Spacing :: Alone ) ;
304
- result. push ( tt) ;
349
+ result. push ( TokenTree :: Token ( token. clone ( ) , Spacing :: Alone ) ) ;
305
350
}
306
351
307
352
// There should be no meta-var declarations in the invocation of a macro.
@@ -466,7 +511,7 @@ fn lockstep_iter_size(
466
511
size. with ( lockstep_iter_size ( tt, interpolations, repeats) )
467
512
} )
468
513
}
469
- TokenTree :: MetaVar ( _, name) | TokenTree :: MetaVarDecl ( _, name, _) => {
514
+ TokenTree :: MetaVar ( _, name, _ ) | TokenTree :: MetaVarDecl ( _, name, _) => {
470
515
let name = MacroRulesNormalizedIdent :: new ( * name) ;
471
516
match lookup_cur_matched ( name, interpolations, repeats) {
472
517
Some ( matched) => match matched {
@@ -611,23 +656,17 @@ fn transcribe_metavar_expr<'a>(
611
656
cx : & ExtCtxt < ' a > ,
612
657
expr : & MetaVarExpr ,
613
658
interp : & FxHashMap < MacroRulesNormalizedIdent , NamedMatch > ,
614
- marker : & mut Marker ,
615
659
repeats : & [ ( usize , usize ) ] ,
616
660
result : & mut Vec < TokenTree > ,
617
661
sp : & DelimSpan ,
618
662
) -> PResult < ' a , ( ) > {
619
- let mut visited_span = || {
620
- let mut span = sp. entire ( ) ;
621
- marker. visit_span ( & mut span) ;
622
- span
623
- } ;
624
663
match * expr {
625
664
MetaVarExpr :: Count ( original_ident, depth) => {
626
665
let matched = matched_from_ident ( cx, original_ident, interp) ?;
627
666
let count = count_repetitions ( cx, depth, matched, repeats, sp) ?;
628
667
let tt = TokenTree :: token_alone (
629
668
TokenKind :: lit ( token:: Integer , sym:: integer ( count) , None ) ,
630
- visited_span ( ) ,
669
+ sp . entire ( ) ,
631
670
) ;
632
671
result. push ( tt) ;
633
672
}
@@ -639,7 +678,7 @@ fn transcribe_metavar_expr<'a>(
639
678
Some ( ( index, _) ) => {
640
679
result. push ( TokenTree :: token_alone (
641
680
TokenKind :: lit ( token:: Integer , sym:: integer ( * index) , None ) ,
642
- visited_span ( ) ,
681
+ sp . entire ( ) ,
643
682
) ) ;
644
683
}
645
684
None => return Err ( out_of_bounds_err ( cx, repeats. len ( ) , sp. entire ( ) , "index" ) ) ,
@@ -648,7 +687,7 @@ fn transcribe_metavar_expr<'a>(
648
687
Some ( ( _, length) ) => {
649
688
result. push ( TokenTree :: token_alone (
650
689
TokenKind :: lit ( token:: Integer , sym:: integer ( * length) , None ) ,
651
- visited_span ( ) ,
690
+ sp . entire ( ) ,
652
691
) ) ;
653
692
}
654
693
None => return Err ( out_of_bounds_err ( cx, repeats. len ( ) , sp. entire ( ) , "length" ) ) ,
0 commit comments