@@ -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