@@ -18,7 +18,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree};
18
18
19
19
use rustc_target:: spec:: abi:: { self , Abi } ;
20
20
use syntax_pos:: { self , BytePos } ;
21
- use syntax_pos:: { DUMMY_SP , FileName } ;
21
+ use syntax_pos:: { DUMMY_SP , FileName , Span } ;
22
22
23
23
use std:: borrow:: Cow ;
24
24
use std:: io:: Read ;
@@ -181,7 +181,46 @@ pub fn literal_to_string(lit: token::Lit) -> String {
181
181
out
182
182
}
183
183
184
+ fn ident_to_string ( ident : ast:: Ident , is_raw : bool ) -> String {
185
+ ident_to_string_ext ( ident. name , is_raw, Some ( ident. span ) )
186
+ }
187
+
188
+ // AST pretty-printer is used as a fallback for turning AST structures into token streams for
189
+ // proc macros. Additionally, proc macros may stringify their input and expect it survive the
190
+ // stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
191
+ // So we need to somehow pretty-print `$crate` in a way preserving at least some of its
192
+ // hygiene data, most importantly name of the crate it refers to.
193
+ // As a result we print `$crate` as `crate` if it refers to the local crate
194
+ // and as `::other_crate_name` if it refers to some other crate.
195
+ // Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
196
+ // but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
197
+ // so we should not perform this lossy conversion if the top level call to the pretty-printer was
198
+ // done for a token stream or a single token.
199
+ fn ident_to_string_ext (
200
+ name : ast:: Name , is_raw : bool , convert_dollar_crate : Option < Span >
201
+ ) -> String {
202
+ if is_raw {
203
+ format ! ( "r#{}" , name)
204
+ } else {
205
+ if name == kw:: DollarCrate {
206
+ if let Some ( span) = convert_dollar_crate {
207
+ let converted = span. ctxt ( ) . dollar_crate_name ( ) ;
208
+ return if converted. is_path_segment_keyword ( ) {
209
+ converted. to_string ( )
210
+ } else {
211
+ format ! ( "::{}" , converted)
212
+ }
213
+ }
214
+ }
215
+ name. to_string ( )
216
+ }
217
+ }
218
+
184
219
pub fn token_kind_to_string ( tok : & TokenKind ) -> String {
220
+ token_kind_to_string_ext ( tok, None )
221
+ }
222
+
223
+ fn token_kind_to_string_ext ( tok : & TokenKind , convert_dollar_crate : Option < Span > ) -> String {
185
224
match * tok {
186
225
token:: Eq => "=" . to_string ( ) ,
187
226
token:: Lt => "<" . to_string ( ) ,
@@ -227,8 +266,7 @@ pub fn token_kind_to_string(tok: &TokenKind) -> String {
227
266
token:: Literal ( lit) => literal_to_string ( lit) ,
228
267
229
268
/* Name components */
230
- token:: Ident ( s, false ) => s. to_string ( ) ,
231
- token:: Ident ( s, true ) => format ! ( "r#{}" , s) ,
269
+ token:: Ident ( s, is_raw) => ident_to_string_ext ( s, is_raw, convert_dollar_crate) ,
232
270
token:: Lifetime ( s) => s. to_string ( ) ,
233
271
234
272
/* Other */
@@ -243,7 +281,12 @@ pub fn token_kind_to_string(tok: &TokenKind) -> String {
243
281
}
244
282
245
283
pub fn token_to_string ( token : & Token ) -> String {
246
- token_kind_to_string ( & token. kind )
284
+ token_to_string_ext ( token, false )
285
+ }
286
+
287
+ fn token_to_string_ext ( token : & Token , convert_dollar_crate : bool ) -> String {
288
+ let convert_dollar_crate = if convert_dollar_crate { Some ( token. span ) } else { None } ;
289
+ token_kind_to_string_ext ( & token. kind , convert_dollar_crate)
247
290
}
248
291
249
292
crate fn nonterminal_to_string ( nt : & Nonterminal ) -> String {
@@ -256,9 +299,8 @@ crate fn nonterminal_to_string(nt: &Nonterminal) -> String {
256
299
token:: NtBlock ( ref e) => block_to_string ( e) ,
257
300
token:: NtStmt ( ref e) => stmt_to_string ( e) ,
258
301
token:: NtPat ( ref e) => pat_to_string ( e) ,
259
- token:: NtIdent ( e, false ) => ident_to_string ( e) ,
260
- token:: NtIdent ( e, true ) => format ! ( "r#{}" , ident_to_string( e) ) ,
261
- token:: NtLifetime ( e) => ident_to_string ( e) ,
302
+ token:: NtIdent ( e, is_raw) => ident_to_string ( e, is_raw) ,
303
+ token:: NtLifetime ( e) => e. to_string ( ) ,
262
304
token:: NtLiteral ( ref e) => expr_to_string ( e) ,
263
305
token:: NtTT ( ref tree) => tt_to_string ( tree. clone ( ) ) ,
264
306
token:: NtImplItem ( ref e) => impl_item_to_string ( e) ,
@@ -293,15 +335,15 @@ pub fn lifetime_to_string(lt: &ast::Lifetime) -> String {
293
335
}
294
336
295
337
pub fn tt_to_string ( tt : tokenstream:: TokenTree ) -> String {
296
- to_string ( |s| s. print_tt ( tt) )
338
+ to_string ( |s| s. print_tt ( tt, false ) )
297
339
}
298
340
299
341
pub fn tts_to_string ( tts : & [ tokenstream:: TokenTree ] ) -> String {
300
- to_string ( |s| s . print_tts ( tts. iter ( ) . cloned ( ) . collect ( ) ) )
342
+ tokens_to_string ( tts. iter ( ) . cloned ( ) . collect ( ) )
301
343
}
302
344
303
345
pub fn tokens_to_string ( tokens : TokenStream ) -> String {
304
- to_string ( |s| s. print_tts ( tokens) )
346
+ to_string ( |s| s. print_tts_ext ( tokens, false ) )
305
347
}
306
348
307
349
pub fn stmt_to_string ( stmt : & ast:: Stmt ) -> String {
@@ -344,10 +386,6 @@ pub fn path_segment_to_string(p: &ast::PathSegment) -> String {
344
386
to_string ( |s| s. print_path_segment ( p, false ) )
345
387
}
346
388
347
- pub fn ident_to_string ( id : ast:: Ident ) -> String {
348
- to_string ( |s| s. print_ident ( id) )
349
- }
350
-
351
389
pub fn vis_to_string ( v : & ast:: Visibility ) -> String {
352
390
to_string ( |s| s. print_visibility ( v) )
353
391
}
@@ -629,11 +667,7 @@ pub trait PrintState<'a> {
629
667
self . writer ( ) . word ( "::" ) ;
630
668
}
631
669
if segment. ident . name != kw:: PathRoot {
632
- if segment. ident . name == kw:: DollarCrate {
633
- self . print_dollar_crate ( segment. ident ) ;
634
- } else {
635
- self . writer ( ) . word ( segment. ident . as_str ( ) . to_string ( ) ) ;
636
- }
670
+ self . writer ( ) . word ( ident_to_string ( segment. ident , segment. ident . is_raw_guess ( ) ) ) ;
637
671
}
638
672
}
639
673
}
@@ -707,10 +741,10 @@ pub trait PrintState<'a> {
707
741
/// appropriate macro, transcribe back into the grammar we just parsed from,
708
742
/// and then pretty-print the resulting AST nodes (so, e.g., we print
709
743
/// expression arguments as expressions). It can be done! I think.
710
- fn print_tt ( & mut self , tt : tokenstream:: TokenTree ) {
744
+ fn print_tt ( & mut self , tt : tokenstream:: TokenTree , convert_dollar_crate : bool ) {
711
745
match tt {
712
746
TokenTree :: Token ( ref token) => {
713
- self . writer ( ) . word ( token_to_string ( & token) ) ;
747
+ self . writer ( ) . word ( token_to_string_ext ( & token, convert_dollar_crate ) ) ;
714
748
match token. kind {
715
749
token:: DocComment ( ..) => {
716
750
self . writer ( ) . hardbreak ( )
@@ -729,12 +763,16 @@ pub trait PrintState<'a> {
729
763
}
730
764
731
765
fn print_tts ( & mut self , tts : tokenstream:: TokenStream ) {
766
+ self . print_tts_ext ( tts, true )
767
+ }
768
+
769
+ fn print_tts_ext ( & mut self , tts : tokenstream:: TokenStream , convert_dollar_crate : bool ) {
732
770
self . ibox ( 0 ) ;
733
771
for ( i, tt) in tts. into_trees ( ) . enumerate ( ) {
734
772
if i != 0 {
735
773
self . writer ( ) . space ( ) ;
736
774
}
737
- self . print_tt ( tt) ;
775
+ self . print_tt ( tt, convert_dollar_crate ) ;
738
776
}
739
777
self . end ( ) ;
740
778
}
@@ -744,21 +782,6 @@ pub trait PrintState<'a> {
744
782
}
745
783
746
784
fn nbsp ( & mut self ) { self . writer ( ) . word ( " " ) }
747
-
748
- // AST pretty-printer is used as a fallback for turning AST structures into token streams for
749
- // proc macros. Additionally, proc macros may stringify their input and expect it survive the
750
- // stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
751
- // So we need to somehow pretty-print `$crate` in paths in a way preserving at least some of
752
- // its hygiene data, most importantly name of the crate it refers to.
753
- // As a result we print `$crate` as `crate` if it refers to the local crate
754
- // and as `::other_crate_name` if it refers to some other crate.
755
- fn print_dollar_crate ( & mut self , ident : ast:: Ident ) {
756
- let name = ident. span . ctxt ( ) . dollar_crate_name ( ) ;
757
- if !ast:: Ident :: with_empty_ctxt ( name) . is_path_segment_keyword ( ) {
758
- self . writer ( ) . word ( "::" ) ;
759
- }
760
- self . writer ( ) . word ( name. as_str ( ) . to_string ( ) )
761
- }
762
785
}
763
786
764
787
impl < ' a > PrintState < ' a > for State < ' a > {
@@ -2287,11 +2310,7 @@ impl<'a> State<'a> {
2287
2310
}
2288
2311
2289
2312
crate fn print_ident ( & mut self , ident : ast:: Ident ) {
2290
- if ident. is_raw_guess ( ) {
2291
- self . s . word ( format ! ( "r#{}" , ident) ) ;
2292
- } else {
2293
- self . s . word ( ident. as_str ( ) . to_string ( ) ) ;
2294
- }
2313
+ self . s . word ( ident_to_string ( ident, ident. is_raw_guess ( ) ) ) ;
2295
2314
self . ann . post ( self , AnnNode :: Ident ( & ident) )
2296
2315
}
2297
2316
@@ -2322,11 +2341,7 @@ impl<'a> State<'a> {
2322
2341
segment : & ast:: PathSegment ,
2323
2342
colons_before_params : bool ) {
2324
2343
if segment. ident . name != kw:: PathRoot {
2325
- if segment. ident . name == kw:: DollarCrate {
2326
- self . print_dollar_crate ( segment. ident ) ;
2327
- } else {
2328
- self . print_ident ( segment. ident ) ;
2329
- }
2344
+ self . print_ident ( segment. ident ) ;
2330
2345
if let Some ( ref args) = segment. args {
2331
2346
self . print_generic_args ( args, colons_before_params) ;
2332
2347
}
0 commit comments