@@ -44,7 +44,7 @@ use std::{cmp, fmt, iter, mem};
44
44
pub enum TokenTree {
45
45
/// A single token. Should never be `OpenDelim` or `CloseDelim`, because
46
46
/// delimiters are implicitly represented by `Delimited`.
47
- Token ( Token , Spacing ) ,
47
+ Token ( Token , FollowedBy ) ,
48
48
/// A delimited sequence of token trees.
49
49
Delimited ( DelimSpan , Delimiter , TokenStream ) ,
50
50
}
@@ -54,7 +54,7 @@ pub enum TokenTree {
54
54
fn _dummy ( )
55
55
where
56
56
Token : sync:: DynSend + sync:: DynSync ,
57
- Spacing : sync:: DynSend + sync:: DynSync ,
57
+ FollowedBy : sync:: DynSend + sync:: DynSync ,
58
58
DelimSpan : sync:: DynSend + sync:: DynSync ,
59
59
Delimiter : sync:: DynSend + sync:: DynSync ,
60
60
TokenStream : sync:: DynSend + sync:: DynSync ,
@@ -89,20 +89,25 @@ impl TokenTree {
89
89
}
90
90
}
91
91
92
- /// Create a `TokenTree::Token` with alone spacing .
93
- pub fn token_alone ( kind : TokenKind , span : Span ) -> TokenTree {
94
- TokenTree :: Token ( Token :: new ( kind, span) , Spacing :: Alone )
92
+ /// Create a `TokenTree::Token` with `FollowedBy::Space` .
93
+ pub fn token_fby_space ( kind : TokenKind , span : Span ) -> TokenTree {
94
+ TokenTree :: Token ( Token :: new ( kind, span) , FollowedBy :: Space )
95
95
}
96
96
97
- /// Create a `TokenTree::Token` with joint spacing.
98
- pub fn token_joint ( kind : TokenKind , span : Span ) -> TokenTree {
99
- TokenTree :: Token ( Token :: new ( kind, span) , Spacing :: Joint )
97
+ /// Create a `TokenTree::Token` with `FollowedBy::Punct`.
98
+ pub fn token_fby_punct ( kind : TokenKind , span : Span ) -> TokenTree {
99
+ TokenTree :: Token ( Token :: new ( kind, span) , FollowedBy :: Punct )
100
+ }
101
+
102
+ /// Create a `TokenTree::Token` with `FollowedBy::Other`.
103
+ pub fn token_fby_other ( kind : TokenKind , span : Span ) -> TokenTree {
104
+ TokenTree :: Token ( Token :: new ( kind, span) , FollowedBy :: Other )
100
105
}
101
106
102
107
pub fn uninterpolate ( & self ) -> Cow < ' _ , TokenTree > {
103
108
match self {
104
- TokenTree :: Token ( token, spacing ) => match token. uninterpolate ( ) {
105
- Cow :: Owned ( token) => Cow :: Owned ( TokenTree :: Token ( token, * spacing ) ) ,
109
+ TokenTree :: Token ( token, fby ) => match token. uninterpolate ( ) {
110
+ Cow :: Owned ( token) => Cow :: Owned ( TokenTree :: Token ( token, * fby ) ) ,
106
111
Cow :: Borrowed ( _) => Cow :: Borrowed ( self ) ,
107
112
} ,
108
113
_ => Cow :: Borrowed ( self ) ,
@@ -182,7 +187,7 @@ pub struct AttrTokenStream(pub Lrc<Vec<AttrTokenTree>>);
182
187
/// Like `TokenTree`, but for `AttrTokenStream`.
183
188
#[ derive( Clone , Debug , Encodable , Decodable ) ]
184
189
pub enum AttrTokenTree {
185
- Token ( Token , Spacing ) ,
190
+ Token ( Token , FollowedBy ) ,
186
191
Delimited ( DelimSpan , Delimiter , AttrTokenStream ) ,
187
192
/// Stores the attributes for an attribute target,
188
193
/// along with the tokens for that attribute target.
@@ -205,8 +210,8 @@ impl AttrTokenStream {
205
210
. 0
206
211
. iter ( )
207
212
. flat_map ( |tree| match & tree {
208
- AttrTokenTree :: Token ( inner, spacing ) => {
209
- smallvec ! [ TokenTree :: Token ( inner. clone( ) , * spacing ) ] . into_iter ( )
213
+ AttrTokenTree :: Token ( inner, fby ) => {
214
+ smallvec ! [ TokenTree :: Token ( inner. clone( ) , * fby ) ] . into_iter ( )
210
215
}
211
216
AttrTokenTree :: Delimited ( span, delim, stream) => {
212
217
smallvec ! [ TokenTree :: Delimited ( * span, * delim, stream. to_tokenstream( ) ) , ]
@@ -307,21 +312,40 @@ pub struct AttributesData {
307
312
#[ derive( Clone , Debug , Default , Encodable , Decodable ) ]
308
313
pub struct TokenStream ( pub ( crate ) Lrc < Vec < TokenTree > > ) ;
309
314
310
- /// Similar to `proc_macro::Spacing`, but for tokens.
311
- ///
312
- /// Note that all `ast::TokenTree::Token` instances have a `Spacing`, but when
313
- /// we convert to `proc_macro::TokenTree` for proc macros only `Punct`
314
- /// `TokenTree`s have a `proc_macro::Spacing`.
315
+ /// Describes what immediately follows a token. Used for pretty-printing and
316
+ /// conversions to `proc_macro::Spacing`.
315
317
#[ derive( Clone , Copy , Debug , PartialEq , Encodable , Decodable , HashStable_Generic ) ]
316
- pub enum Spacing {
317
- /// The token is not immediately followed by an operator token (as
318
- /// determined by `Token::is_op`). E.g. a `+` token is `Alone` in `+ =`,
319
- /// `+/*foo*/=`, `+ident`, and `+()`.
320
- Alone ,
321
-
322
- /// The token is immediately followed by an operator token. E.g. a `+`
323
- /// token is `Joint` in `+=` and `++`.
324
- Joint ,
318
+ pub enum FollowedBy {
319
+ /// The token is immediately followed by whitespace or a non-doc comment.
320
+ /// When constructing token streams, use this for each token that should be
321
+ /// pretty-printed with a space after it.
322
+ ///
323
+ /// Converts to `Spacing::Alone`, and `Spacing::Alone` converts back to
324
+ /// this.
325
+ Space ,
326
+
327
+ /// The token is immediately followed by punctuation (as determined by
328
+ /// `Token::is_punct`). When constructing token streams, use this for each
329
+ /// token that (a) should be pretty-printed without a space after it, and
330
+ /// (b) is followed by an punctuation token.
331
+ ///
332
+ /// Converts to `Spacing::Joint`, and `Spacing::Joint` converts back to
333
+ /// this.
334
+ Punct ,
335
+
336
+ /// The token is immediately followed by something else: an identifier,
337
+ /// lifetime, literal, delimiter, doc comment, or EOF. When constructing
338
+ /// token streams, use this for each token that (a) should be
339
+ /// pretty-printed without a space after it, and (b) is followed by a
340
+ /// non-punctuation token.
341
+ ///
342
+ /// Converts to `Spacing::Alone`, but `Spacing::Alone` converts back to
343
+ /// `FollowedBy::Space`. Because of that, pretty-printing of `TokenStream`s
344
+ /// produced by proc macros is unavoidably uglier (with more whitespace
345
+ /// between tokens) than pretty-printing of `TokenStream`'s produced by
346
+ /// other means (i.e. user-written code, internally constructed token
347
+ /// streams, and token streams produced by declarative macros).
348
+ Other ,
325
349
}
326
350
327
351
impl TokenStream {
@@ -336,7 +360,7 @@ impl TokenStream {
336
360
let sp = match ( & ts, & next) {
337
361
( _, TokenTree :: Token ( Token { kind : token:: Comma , .. } , _) ) => continue ,
338
362
(
339
- TokenTree :: Token ( token_left, Spacing :: Alone ) ,
363
+ TokenTree :: Token ( token_left, FollowedBy :: Space | FollowedBy :: Other ) ,
340
364
TokenTree :: Token ( token_right, _) ,
341
365
) if ( ( token_left. is_ident ( ) && !token_left. is_reserved_ident ( ) )
342
366
|| token_left. is_lit ( ) )
@@ -349,7 +373,7 @@ impl TokenStream {
349
373
_ => continue ,
350
374
} ;
351
375
let sp = sp. shrink_to_hi ( ) ;
352
- let comma = TokenTree :: token_alone ( token:: Comma , sp) ;
376
+ let comma = TokenTree :: token_fby_space ( token:: Comma , sp) ;
353
377
suggestion = Some ( ( pos, comma, sp) ) ;
354
378
}
355
379
}
@@ -425,14 +449,22 @@ impl TokenStream {
425
449
self
426
450
}
427
451
428
- /// Create a token stream containing a single token with alone spacing.
429
- pub fn token_alone ( kind : TokenKind , span : Span ) -> TokenStream {
430
- TokenStream :: new ( vec ! [ TokenTree :: token_alone( kind, span) ] )
452
+ /// Create a token stream containing a single token with
453
+ /// `FollowedBy::Space`.
454
+ pub fn token_fby_space ( kind : TokenKind , span : Span ) -> TokenStream {
455
+ TokenStream :: new ( vec ! [ TokenTree :: token_fby_space( kind, span) ] )
456
+ }
457
+
458
+ /// Create a token stream containing a single token with
459
+ /// `FollowedBy::Punct`.
460
+ pub fn token_fby_punct ( kind : TokenKind , span : Span ) -> TokenStream {
461
+ TokenStream :: new ( vec ! [ TokenTree :: token_fby_punct( kind, span) ] )
431
462
}
432
463
433
- /// Create a token stream containing a single token with joint spacing.
434
- pub fn token_joint ( kind : TokenKind , span : Span ) -> TokenStream {
435
- TokenStream :: new ( vec ! [ TokenTree :: token_joint( kind, span) ] )
464
+ /// Create a token stream containing a single token with
465
+ /// `FollowedBy::Other`.
466
+ pub fn token_fby_other ( kind : TokenKind , span : Span ) -> TokenStream {
467
+ TokenStream :: new ( vec ! [ TokenTree :: token_fby_other( kind, span) ] )
436
468
}
437
469
438
470
/// Create a token stream containing a single `Delimited`.
@@ -458,16 +490,16 @@ impl TokenStream {
458
490
pub fn from_nonterminal_ast ( nt : & Nonterminal ) -> TokenStream {
459
491
match nt {
460
492
Nonterminal :: NtIdent ( ident, is_raw) => {
461
- TokenStream :: token_alone ( token:: Ident ( ident. name , * is_raw) , ident. span )
493
+ TokenStream :: token_fby_space ( token:: Ident ( ident. name , * is_raw) , ident. span )
462
494
}
463
495
Nonterminal :: NtLifetime ( ident) => {
464
- TokenStream :: token_alone ( token:: Lifetime ( ident. name ) , ident. span )
496
+ TokenStream :: token_fby_space ( token:: Lifetime ( ident. name ) , ident. span )
465
497
}
466
498
Nonterminal :: NtItem ( item) => TokenStream :: from_ast ( item) ,
467
499
Nonterminal :: NtBlock ( block) => TokenStream :: from_ast ( block) ,
468
500
Nonterminal :: NtStmt ( stmt) if let StmtKind :: Empty = stmt. kind => {
469
501
// FIXME: Properly collect tokens for empty statements.
470
- TokenStream :: token_alone ( token:: Semi , stmt. span )
502
+ TokenStream :: token_fby_space ( token:: Semi , stmt. span )
471
503
}
472
504
Nonterminal :: NtStmt ( stmt) => TokenStream :: from_ast ( stmt) ,
473
505
Nonterminal :: NtPat ( pat) => TokenStream :: from_ast ( pat) ,
@@ -479,23 +511,23 @@ impl TokenStream {
479
511
}
480
512
}
481
513
482
- fn flatten_token ( token : & Token , spacing : Spacing ) -> TokenTree {
514
+ fn flatten_token ( token : & Token , fby : FollowedBy ) -> TokenTree {
483
515
match & token. kind {
484
516
token:: Interpolated ( nt) if let token:: NtIdent ( ident, is_raw) = * * nt => {
485
- TokenTree :: Token ( Token :: new ( token:: Ident ( ident. name , is_raw) , ident. span ) , spacing )
517
+ TokenTree :: Token ( Token :: new ( token:: Ident ( ident. name , is_raw) , ident. span ) , fby )
486
518
}
487
519
token:: Interpolated ( nt) => TokenTree :: Delimited (
488
520
DelimSpan :: from_single ( token. span ) ,
489
521
Delimiter :: Invisible ,
490
522
TokenStream :: from_nonterminal_ast ( nt) . flattened ( ) ,
491
523
) ,
492
- _ => TokenTree :: Token ( token. clone ( ) , spacing ) ,
524
+ _ => TokenTree :: Token ( token. clone ( ) , fby ) ,
493
525
}
494
526
}
495
527
496
528
fn flatten_token_tree ( tree : & TokenTree ) -> TokenTree {
497
529
match tree {
498
- TokenTree :: Token ( token, spacing ) => TokenStream :: flatten_token ( token, * spacing ) ,
530
+ TokenTree :: Token ( token, fby ) => TokenStream :: flatten_token ( token, * fby ) ,
499
531
TokenTree :: Delimited ( span, delim, tts) => {
500
532
TokenTree :: Delimited ( * span, * delim, tts. flattened ( ) )
501
533
}
@@ -521,13 +553,13 @@ impl TokenStream {
521
553
// If `vec` is not empty, try to glue `tt` onto its last token. The return
522
554
// value indicates if gluing took place.
523
555
fn try_glue_to_last ( vec : & mut Vec < TokenTree > , tt : & TokenTree ) -> bool {
524
- if let Some ( TokenTree :: Token ( last_tok, Spacing :: Joint ) ) = vec. last ( )
525
- && let TokenTree :: Token ( tok, spacing ) = tt
556
+ if let Some ( TokenTree :: Token ( last_tok, FollowedBy :: Punct ) ) = vec. last ( )
557
+ && let TokenTree :: Token ( tok, fby ) = tt
526
558
&& let Some ( glued_tok) = last_tok. glue ( tok)
527
559
{
528
560
// ...then overwrite the last token tree in `vec` with the
529
561
// glued token, and skip the first token tree from `stream`.
530
- * vec. last_mut ( ) . unwrap ( ) = TokenTree :: Token ( glued_tok, * spacing ) ;
562
+ * vec. last_mut ( ) . unwrap ( ) = TokenTree :: Token ( glued_tok, * fby ) ;
531
563
true
532
564
} else {
533
565
false
@@ -583,7 +615,7 @@ impl TokenStream {
583
615
match tt {
584
616
& TokenTree :: Token (
585
617
Token { kind : token:: DocComment ( _, attr_style, data) , span } ,
586
- _spacing ,
618
+ _fby ,
587
619
) => {
588
620
let desugared = desugared_tts ( attr_style, data, span) ;
589
621
let desugared_len = desugared. len ( ) ;
@@ -630,9 +662,9 @@ impl TokenStream {
630
662
delim_span,
631
663
Delimiter :: Bracket ,
632
664
[
633
- TokenTree :: token_alone ( token:: Ident ( sym:: doc, false ) , span) ,
634
- TokenTree :: token_alone ( token:: Eq , span) ,
635
- TokenTree :: token_alone (
665
+ TokenTree :: token_fby_space ( token:: Ident ( sym:: doc, false ) , span) ,
666
+ TokenTree :: token_fby_space ( token:: Eq , span) ,
667
+ TokenTree :: token_fby_space (
636
668
TokenKind :: lit ( token:: StrRaw ( num_of_hashes) , data, None ) ,
637
669
span,
638
670
) ,
@@ -643,12 +675,12 @@ impl TokenStream {
643
675
644
676
if attr_style == AttrStyle :: Inner {
645
677
vec ! [
646
- TokenTree :: token_alone ( token:: Pound , span) ,
647
- TokenTree :: token_alone ( token:: Not , span) ,
678
+ TokenTree :: token_fby_space ( token:: Pound , span) ,
679
+ TokenTree :: token_fby_space ( token:: Not , span) ,
648
680
body,
649
681
]
650
682
} else {
651
- vec ! [ TokenTree :: token_alone ( token:: Pound , span) , body]
683
+ vec ! [ TokenTree :: token_fby_space ( token:: Pound , span) , body]
652
684
}
653
685
}
654
686
}
0 commit comments