1- use crate :: ast:: Ident ;
1+ use crate :: ast:: { Ident , Mac } ;
22use crate :: ext:: base:: ExtCtxt ;
3- use crate :: ext:: expand:: Marker ;
43use crate :: ext:: tt:: macro_parser:: { MatchedNonterminal , MatchedSeq , NamedMatch } ;
54use crate :: ext:: tt:: quoted;
6- use crate :: mut_visit:: noop_visit_tt ;
5+ use crate :: mut_visit:: { self , MutVisitor } ;
76use crate :: parse:: token:: { self , NtTT , Token } ;
87use crate :: tokenstream:: { DelimSpan , TokenStream , TokenTree , TreeAndJoint } ;
98
109use smallvec:: { smallvec, SmallVec } ;
1110
1211use rustc_data_structures:: fx:: FxHashMap ;
1312use rustc_data_structures:: sync:: Lrc ;
13+ use syntax_pos:: hygiene:: { ExpnId , Transparency } ;
14+ use syntax_pos:: Span ;
15+
1416use std:: mem;
1517
18+ // A Marker adds the given mark to the syntax context.
19+ struct Marker ( ExpnId , Transparency ) ;
20+
21+ impl MutVisitor for Marker {
22+ fn visit_span ( & mut self , span : & mut Span ) {
23+ * span = span. apply_mark ( self . 0 , self . 1 )
24+ }
25+
26+ fn visit_mac ( & mut self , mac : & mut Mac ) {
27+ mut_visit:: noop_visit_mac ( mac, self )
28+ }
29+ }
30+
31+ impl Marker {
32+ fn visit_delim_span ( & mut self , dspan : & mut DelimSpan ) {
33+ self . visit_span ( & mut dspan. open ) ;
34+ self . visit_span ( & mut dspan. close ) ;
35+ }
36+ }
37+
1638/// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
1739enum Frame {
1840 Delimited { forest : Lrc < quoted:: Delimited > , idx : usize , span : DelimSpan } ,
@@ -68,6 +90,7 @@ pub(super) fn transcribe(
6890 cx : & ExtCtxt < ' _ > ,
6991 interp : & FxHashMap < Ident , NamedMatch > ,
7092 src : Vec < quoted:: TokenTree > ,
93+ transparency : Transparency ,
7194) -> TokenStream {
7295 // Nothing for us to transcribe...
7396 if src. is_empty ( ) {
@@ -96,6 +119,7 @@ pub(super) fn transcribe(
96119 // again, and we are done transcribing.
97120 let mut result: Vec < TreeAndJoint > = Vec :: new ( ) ;
98121 let mut result_stack = Vec :: new ( ) ;
122+ let mut marker = Marker ( cx. current_expansion . id , transparency) ;
99123
100124 loop {
101125 // Look at the last frame on the stack.
@@ -207,7 +231,7 @@ pub(super) fn transcribe(
207231 }
208232
209233 // Replace the meta-var with the matched token tree from the invocation.
210- quoted:: TokenTree :: MetaVar ( mut sp, ident) => {
234+ quoted:: TokenTree :: MetaVar ( mut sp, mut ident) => {
211235 // Find the matched nonterminal from the macro invocation, and use it to replace
212236 // the meta-var.
213237 if let Some ( cur_matched) = lookup_cur_matched ( ident, interp, & repeats) {
@@ -218,7 +242,7 @@ pub(super) fn transcribe(
218242 if let NtTT ( ref tt) = * * nt {
219243 result. push ( tt. clone ( ) . into ( ) ) ;
220244 } else {
221- sp = sp . apply_mark ( cx . current_expansion . id ) ;
245+ marker . visit_span ( & mut sp ) ;
222246 let token = TokenTree :: token ( token:: Interpolated ( nt. clone ( ) ) , sp) ;
223247 result. push ( token. into ( ) ) ;
224248 }
@@ -232,9 +256,8 @@ pub(super) fn transcribe(
232256 } else {
233257 // If we aren't able to match the meta-var, we push it back into the result but
234258 // with modified syntax context. (I believe this supports nested macros).
235- let ident =
236- Ident :: new ( ident. name , ident. span . apply_mark ( cx. current_expansion . id ) ) ;
237- sp = sp. apply_mark ( cx. current_expansion . id ) ;
259+ marker. visit_span ( & mut sp) ;
260+ marker. visit_ident ( & mut ident) ;
238261 result. push ( TokenTree :: token ( token:: Dollar , sp) . into ( ) ) ;
239262 result. push ( TokenTree :: Token ( Token :: from_ast_ident ( ident) ) . into ( ) ) ;
240263 }
@@ -246,17 +269,16 @@ pub(super) fn transcribe(
246269 // jump back out of the Delimited, pop the result_stack and add the new results back to
247270 // the previous results (from outside the Delimited).
248271 quoted:: TokenTree :: Delimited ( mut span, delimited) => {
249- span = span . apply_mark ( cx . current_expansion . id ) ;
272+ marker . visit_delim_span ( & mut span ) ;
250273 stack. push ( Frame :: Delimited { forest : delimited, idx : 0 , span } ) ;
251274 result_stack. push ( mem:: take ( & mut result) ) ;
252275 }
253276
254277 // Nothing much to do here. Just push the token to the result, being careful to
255278 // preserve syntax context.
256279 quoted:: TokenTree :: Token ( token) => {
257- let mut marker = Marker ( cx. current_expansion . id ) ;
258280 let mut tt = TokenTree :: Token ( token) ;
259- noop_visit_tt ( & mut tt, & mut marker ) ;
281+ marker . visit_tt ( & mut tt) ;
260282 result. push ( tt. into ( ) ) ;
261283 }
262284
0 commit comments