@@ -76,6 +76,55 @@ impl<'a> Iterator for Frame<'a> {
7676 }
7777}
7878
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+
79128/// This can do Macro-By-Example transcription.
80129/// - `interp` is a map of meta-variables to the tokens (non-terminals) they matched in the
81130/// invocation. We are assuming we already know there is a match.
@@ -108,11 +157,15 @@ pub(super) fn transcribe<'a>(
108157 return Ok ( TokenStream :: default ( ) ) ;
109158 }
110159
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+
111164 // We descend into the RHS (`src`), expanding things as we go. This stack contains the things
112165 // we have yet to expand/are still expanding. We start the stack off with the whole RHS. The
113166 // choice of spacing values doesn't matter.
114167 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 ) ) ] ;
116169
117170 // As we descend in the RHS, we will need to be able to match nested sequences of matchers.
118171 // `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>(
132185 // again, and we are done transcribing.
133186 let mut result: Vec < TokenTree > = Vec :: new ( ) ;
134187 let mut result_stack = Vec :: new ( ) ;
135- let mut marker = Marker ( cx. current_expansion . id , transparency, Default :: default ( ) ) ;
136188
137189 loop {
138190 // Look at the last frame on the stack.
@@ -245,10 +297,11 @@ pub(super) fn transcribe<'a>(
245297 }
246298
247299 // 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;
249302 // Find the matched nonterminal from the macro invocation, and use it to replace
250303 // the meta-var.
251- let ident = MacroRulesNormalizedIdent :: new ( original_ident) ;
304+ let ident = MacroRulesNormalizedIdent :: new ( * original_ident) ;
252305 if let Some ( cur_matched) = lookup_cur_matched ( ident, interp, & repeats) {
253306 match cur_matched {
254307 MatchedTokenTree ( tt) => {
@@ -260,7 +313,6 @@ pub(super) fn transcribe<'a>(
260313 // Other variables are emitted into the output stream as groups with
261314 // `Delimiter::Invisible` to maintain parsing priorities.
262315 // `Interpolated` is currently used for such groups in rustc parser.
263- marker. visit_span ( & mut sp) ;
264316 result
265317 . push ( TokenTree :: token_alone ( token:: Interpolated ( nt. clone ( ) ) , sp) ) ;
266318 }
@@ -272,33 +324,30 @@ pub(super) fn transcribe<'a>(
272324 } else {
273325 // If we aren't able to match the meta-var, we push it back into the result but
274326 // with modified syntax context. (I believe this supports nested macros).
275- marker. visit_span ( & mut sp) ;
276- marker. visit_ident ( & mut original_ident) ;
277327 result. push ( TokenTree :: token_joint_hidden ( token:: Dollar , sp) ) ;
278328 result. push ( TokenTree :: Token (
279- Token :: from_ast_ident ( original_ident) ,
329+ Token :: from_ast_ident ( Ident :: new ( original_ident. name , * marked_span ) ) ,
280330 Spacing :: Alone ,
281331 ) ) ;
282332 }
283333 }
284334
285335 // Replace meta-variable expressions with the result of their expansion.
286336 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) ?;
288338 }
289339
290340 // If we are entering a new delimiter, we push its contents to the `stack` to be
291341 // processed, and we push all of the currently produced results to the `result_stack`.
292342 // We will produce all of the results of the inside of the `Delimited` and then we will
293343 // jump back out of the Delimited, pop the result_stack and add the new results back to
294344 // 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) => {
297346 stack. push ( Frame :: Delimited {
298347 tts : & delimited. tts ,
299348 delim : delimited. delim ,
300349 idx : 0 ,
301- span,
350+ span : * span ,
302351 spacing : * spacing,
303352 } ) ;
304353 result_stack. push ( mem:: take ( & mut result) ) ;
@@ -307,10 +356,7 @@ pub(super) fn transcribe<'a>(
307356 // Nothing much to do here. Just push the token to the result, being careful to
308357 // preserve syntax context.
309358 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 ) ) ;
314360 }
315361
316362 // There should be no meta-var declarations in the invocation of a macro.
@@ -475,7 +521,7 @@ fn lockstep_iter_size(
475521 size. with ( lockstep_iter_size ( tt, interpolations, repeats) )
476522 } )
477523 }
478- TokenTree :: MetaVar ( _, name) | TokenTree :: MetaVarDecl ( _, name, _) => {
524+ TokenTree :: MetaVar ( _, name, _ ) | TokenTree :: MetaVarDecl ( _, name, _) => {
479525 let name = MacroRulesNormalizedIdent :: new ( * name) ;
480526 match lookup_cur_matched ( name, interpolations, repeats) {
481527 Some ( matched) => match matched {
@@ -620,23 +666,17 @@ fn transcribe_metavar_expr<'a>(
620666 cx : & ExtCtxt < ' a > ,
621667 expr : & MetaVarExpr ,
622668 interp : & FxHashMap < MacroRulesNormalizedIdent , NamedMatch > ,
623- marker : & mut Marker ,
624669 repeats : & [ ( usize , usize ) ] ,
625670 result : & mut Vec < TokenTree > ,
626671 sp : & DelimSpan ,
627672) -> PResult < ' a , ( ) > {
628- let mut visited_span = || {
629- let mut span = sp. entire ( ) ;
630- marker. visit_span ( & mut span) ;
631- span
632- } ;
633673 match * expr {
634674 MetaVarExpr :: Count ( original_ident, depth) => {
635675 let matched = matched_from_ident ( cx, original_ident, interp) ?;
636676 let count = count_repetitions ( cx, depth, matched, repeats, sp) ?;
637677 let tt = TokenTree :: token_alone (
638678 TokenKind :: lit ( token:: Integer , sym:: integer ( count) , None ) ,
639- visited_span ( ) ,
679+ sp . entire ( ) ,
640680 ) ;
641681 result. push ( tt) ;
642682 }
@@ -648,7 +688,7 @@ fn transcribe_metavar_expr<'a>(
648688 Some ( ( index, _) ) => {
649689 result. push ( TokenTree :: token_alone (
650690 TokenKind :: lit ( token:: Integer , sym:: integer ( * index) , None ) ,
651- visited_span ( ) ,
691+ sp . entire ( ) ,
652692 ) ) ;
653693 }
654694 None => return Err ( out_of_bounds_err ( cx, repeats. len ( ) , sp. entire ( ) , "index" ) ) ,
@@ -657,7 +697,7 @@ fn transcribe_metavar_expr<'a>(
657697 Some ( ( _, length) ) => {
658698 result. push ( TokenTree :: token_alone (
659699 TokenKind :: lit ( token:: Integer , sym:: integer ( * length) , None ) ,
660- visited_span ( ) ,
700+ sp . entire ( ) ,
661701 ) ) ;
662702 }
663703 None => return Err ( out_of_bounds_err ( cx, repeats. len ( ) , sp. entire ( ) , "length" ) ) ,
0 commit comments