1
- use crate :: ast:: Ident ;
1
+ use crate :: ast:: { Ident , Mac } ;
2
2
use crate :: ext:: base:: ExtCtxt ;
3
- use crate :: ext:: expand:: Marker ;
4
3
use crate :: ext:: tt:: macro_parser:: { MatchedNonterminal , MatchedSeq , NamedMatch } ;
5
4
use crate :: ext:: tt:: quoted;
6
- use crate :: mut_visit:: noop_visit_tt ;
5
+ use crate :: mut_visit:: { self , MutVisitor } ;
7
6
use crate :: parse:: token:: { self , NtTT , Token } ;
8
7
use crate :: tokenstream:: { DelimSpan , TokenStream , TokenTree , TreeAndJoint } ;
9
8
10
9
use smallvec:: { smallvec, SmallVec } ;
11
10
12
11
use rustc_data_structures:: fx:: FxHashMap ;
13
12
use rustc_data_structures:: sync:: Lrc ;
13
+ use syntax_pos:: hygiene:: { ExpnId , Transparency } ;
14
+ use syntax_pos:: Span ;
15
+
14
16
use std:: mem;
15
17
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
+
16
38
/// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
17
39
enum Frame {
18
40
Delimited { forest : Lrc < quoted:: Delimited > , idx : usize , span : DelimSpan } ,
@@ -68,6 +90,7 @@ pub(super) fn transcribe(
68
90
cx : & ExtCtxt < ' _ > ,
69
91
interp : & FxHashMap < Ident , NamedMatch > ,
70
92
src : Vec < quoted:: TokenTree > ,
93
+ transparency : Transparency ,
71
94
) -> TokenStream {
72
95
// Nothing for us to transcribe...
73
96
if src. is_empty ( ) {
@@ -96,6 +119,7 @@ pub(super) fn transcribe(
96
119
// again, and we are done transcribing.
97
120
let mut result: Vec < TreeAndJoint > = Vec :: new ( ) ;
98
121
let mut result_stack = Vec :: new ( ) ;
122
+ let mut marker = Marker ( cx. current_expansion . id , transparency) ;
99
123
100
124
loop {
101
125
// Look at the last frame on the stack.
@@ -207,7 +231,7 @@ pub(super) fn transcribe(
207
231
}
208
232
209
233
// 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) => {
211
235
// Find the matched nonterminal from the macro invocation, and use it to replace
212
236
// the meta-var.
213
237
if let Some ( cur_matched) = lookup_cur_matched ( ident, interp, & repeats) {
@@ -218,7 +242,7 @@ pub(super) fn transcribe(
218
242
if let NtTT ( ref tt) = * * nt {
219
243
result. push ( tt. clone ( ) . into ( ) ) ;
220
244
} else {
221
- sp = sp . apply_mark ( cx . current_expansion . id ) ;
245
+ marker . visit_span ( & mut sp ) ;
222
246
let token = TokenTree :: token ( token:: Interpolated ( nt. clone ( ) ) , sp) ;
223
247
result. push ( token. into ( ) ) ;
224
248
}
@@ -232,9 +256,8 @@ pub(super) fn transcribe(
232
256
} else {
233
257
// If we aren't able to match the meta-var, we push it back into the result but
234
258
// 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) ;
238
261
result. push ( TokenTree :: token ( token:: Dollar , sp) . into ( ) ) ;
239
262
result. push ( TokenTree :: Token ( Token :: from_ast_ident ( ident) ) . into ( ) ) ;
240
263
}
@@ -246,17 +269,16 @@ pub(super) fn transcribe(
246
269
// jump back out of the Delimited, pop the result_stack and add the new results back to
247
270
// the previous results (from outside the Delimited).
248
271
quoted:: TokenTree :: Delimited ( mut span, delimited) => {
249
- span = span . apply_mark ( cx . current_expansion . id ) ;
272
+ marker . visit_delim_span ( & mut span ) ;
250
273
stack. push ( Frame :: Delimited { forest : delimited, idx : 0 , span } ) ;
251
274
result_stack. push ( mem:: take ( & mut result) ) ;
252
275
}
253
276
254
277
// Nothing much to do here. Just push the token to the result, being careful to
255
278
// preserve syntax context.
256
279
quoted:: TokenTree :: Token ( token) => {
257
- let mut marker = Marker ( cx. current_expansion . id ) ;
258
280
let mut tt = TokenTree :: Token ( token) ;
259
- noop_visit_tt ( & mut tt, & mut marker ) ;
281
+ marker . visit_tt ( & mut tt) ;
260
282
result. push ( tt. into ( ) ) ;
261
283
}
262
284
0 commit comments