@@ -67,6 +67,55 @@ impl<'a> Iterator for Frame<'a> {
6767 }
6868}
6969
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+
70119/// This can do Macro-By-Example transcription.
71120/// - `interp` is a map of meta-variables to the tokens (non-terminals) they matched in the
72121/// invocation. We are assuming we already know there is a match.
@@ -99,11 +148,14 @@ pub(super) fn transcribe<'a>(
99148 return Ok ( TokenStream :: default ( ) ) ;
100149 }
101150
151+ let mut src = src. clone ( ) ;
152+ mark_delimited ( & mut src, & mut Marker ( cx. current_expansion . id , transparency) ) ;
153+
102154 // We descend into the RHS (`src`), expanding things as we go. This stack contains the things
103155 // we have yet to expand/are still expanding. We start the stack off with the whole RHS. The
104156 // choice of spacing values doesn't matter.
105157 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 ) ) ] ;
107159
108160 // As we descend in the RHS, we will need to be able to match nested sequences of matchers.
109161 // `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>(
123175 // again, and we are done transcribing.
124176 let mut result: Vec < TokenTree > = Vec :: new ( ) ;
125177 let mut result_stack = Vec :: new ( ) ;
126- let mut marker = Marker ( cx. current_expansion . id , transparency) ;
127178
128179 loop {
129180 // Look at the last frame on the stack.
@@ -236,10 +287,11 @@ pub(super) fn transcribe<'a>(
236287 }
237288
238289 // 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;
240292 // Find the matched nonterminal from the macro invocation, and use it to replace
241293 // the meta-var.
242- let ident = MacroRulesNormalizedIdent :: new ( original_ident) ;
294+ let ident = MacroRulesNormalizedIdent :: new ( * original_ident) ;
243295 if let Some ( cur_matched) = lookup_cur_matched ( ident, interp, & repeats) {
244296 match cur_matched {
245297 MatchedTokenTree ( tt) => {
@@ -251,7 +303,6 @@ pub(super) fn transcribe<'a>(
251303 // Other variables are emitted into the output stream as groups with
252304 // `Delimiter::Invisible` to maintain parsing priorities.
253305 // `Interpolated` is currently used for such groups in rustc parser.
254- marker. visit_span ( & mut sp) ;
255306 result
256307 . push ( TokenTree :: token_alone ( token:: Interpolated ( nt. clone ( ) ) , sp) ) ;
257308 }
@@ -263,33 +314,30 @@ pub(super) fn transcribe<'a>(
263314 } else {
264315 // If we aren't able to match the meta-var, we push it back into the result but
265316 // with modified syntax context. (I believe this supports nested macros).
266- marker. visit_span ( & mut sp) ;
267- marker. visit_ident ( & mut original_ident) ;
268317 result. push ( TokenTree :: token_joint_hidden ( token:: Dollar , sp) ) ;
269318 result. push ( TokenTree :: Token (
270- Token :: from_ast_ident ( original_ident) ,
319+ Token :: from_ast_ident ( Ident :: new ( original_ident. name , * marked_span ) ) ,
271320 Spacing :: Alone ,
272321 ) ) ;
273322 }
274323 }
275324
276325 // Replace meta-variable expressions with the result of their expansion.
277326 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) ?;
279328 }
280329
281330 // If we are entering a new delimiter, we push its contents to the `stack` to be
282331 // processed, and we push all of the currently produced results to the `result_stack`.
283332 // We will produce all of the results of the inside of the `Delimited` and then we will
284333 // jump back out of the Delimited, pop the result_stack and add the new results back to
285334 // 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) => {
288336 stack. push ( Frame :: Delimited {
289337 tts : & delimited. tts ,
290338 delim : delimited. delim ,
291339 idx : 0 ,
292- span,
340+ span : * span ,
293341 spacing : * spacing,
294342 } ) ;
295343 result_stack. push ( mem:: take ( & mut result) ) ;
@@ -298,10 +346,7 @@ pub(super) fn transcribe<'a>(
298346 // Nothing much to do here. Just push the token to the result, being careful to
299347 // preserve syntax context.
300348 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 ) ) ;
305350 }
306351
307352 // There should be no meta-var declarations in the invocation of a macro.
@@ -466,7 +511,7 @@ fn lockstep_iter_size(
466511 size. with ( lockstep_iter_size ( tt, interpolations, repeats) )
467512 } )
468513 }
469- TokenTree :: MetaVar ( _, name) | TokenTree :: MetaVarDecl ( _, name, _) => {
514+ TokenTree :: MetaVar ( _, name, _ ) | TokenTree :: MetaVarDecl ( _, name, _) => {
470515 let name = MacroRulesNormalizedIdent :: new ( * name) ;
471516 match lookup_cur_matched ( name, interpolations, repeats) {
472517 Some ( matched) => match matched {
@@ -611,23 +656,17 @@ fn transcribe_metavar_expr<'a>(
611656 cx : & ExtCtxt < ' a > ,
612657 expr : & MetaVarExpr ,
613658 interp : & FxHashMap < MacroRulesNormalizedIdent , NamedMatch > ,
614- marker : & mut Marker ,
615659 repeats : & [ ( usize , usize ) ] ,
616660 result : & mut Vec < TokenTree > ,
617661 sp : & DelimSpan ,
618662) -> PResult < ' a , ( ) > {
619- let mut visited_span = || {
620- let mut span = sp. entire ( ) ;
621- marker. visit_span ( & mut span) ;
622- span
623- } ;
624663 match * expr {
625664 MetaVarExpr :: Count ( original_ident, depth) => {
626665 let matched = matched_from_ident ( cx, original_ident, interp) ?;
627666 let count = count_repetitions ( cx, depth, matched, repeats, sp) ?;
628667 let tt = TokenTree :: token_alone (
629668 TokenKind :: lit ( token:: Integer , sym:: integer ( count) , None ) ,
630- visited_span ( ) ,
669+ sp . entire ( ) ,
631670 ) ;
632671 result. push ( tt) ;
633672 }
@@ -639,7 +678,7 @@ fn transcribe_metavar_expr<'a>(
639678 Some ( ( index, _) ) => {
640679 result. push ( TokenTree :: token_alone (
641680 TokenKind :: lit ( token:: Integer , sym:: integer ( * index) , None ) ,
642- visited_span ( ) ,
681+ sp . entire ( ) ,
643682 ) ) ;
644683 }
645684 None => return Err ( out_of_bounds_err ( cx, repeats. len ( ) , sp. entire ( ) , "index" ) ) ,
@@ -648,7 +687,7 @@ fn transcribe_metavar_expr<'a>(
648687 Some ( ( _, length) ) => {
649688 result. push ( TokenTree :: token_alone (
650689 TokenKind :: lit ( token:: Integer , sym:: integer ( * length) , None ) ,
651- visited_span ( ) ,
690+ sp . entire ( ) ,
652691 ) ) ;
653692 }
654693 None => return Err ( out_of_bounds_err ( cx, repeats. len ( ) , sp. entire ( ) , "length" ) ) ,
0 commit comments