@@ -44,7 +44,7 @@ use std::{cmp, fmt, iter, mem};
4444pub enum TokenTree {
4545 /// A single token. Should never be `OpenDelim` or `CloseDelim`, because
4646 /// delimiters are implicitly represented by `Delimited`.
47- Token ( Token , Spacing ) ,
47+ Token ( Token , FollowedBy ) ,
4848 /// A delimited sequence of token trees.
4949 Delimited ( DelimSpan , Delimiter , TokenStream ) ,
5050}
@@ -54,7 +54,7 @@ pub enum TokenTree {
5454fn _dummy ( )
5555where
5656 Token : sync:: DynSend + sync:: DynSync ,
57- Spacing : sync:: DynSend + sync:: DynSync ,
57+ FollowedBy : sync:: DynSend + sync:: DynSync ,
5858 DelimSpan : sync:: DynSend + sync:: DynSync ,
5959 Delimiter : sync:: DynSend + sync:: DynSync ,
6060 TokenStream : sync:: DynSend + sync:: DynSync ,
@@ -89,20 +89,25 @@ impl TokenTree {
8989 }
9090 }
9191
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 )
9595 }
9696
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 )
100105 }
101106
102107 pub fn uninterpolate ( & self ) -> Cow < ' _ , TokenTree > {
103108 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 ) ) ,
106111 Cow :: Borrowed ( _) => Cow :: Borrowed ( self ) ,
107112 } ,
108113 _ => Cow :: Borrowed ( self ) ,
@@ -182,7 +187,7 @@ pub struct AttrTokenStream(pub Lrc<Vec<AttrTokenTree>>);
182187/// Like `TokenTree`, but for `AttrTokenStream`.
183188#[ derive( Clone , Debug , Encodable , Decodable ) ]
184189pub enum AttrTokenTree {
185- Token ( Token , Spacing ) ,
190+ Token ( Token , FollowedBy ) ,
186191 Delimited ( DelimSpan , Delimiter , AttrTokenStream ) ,
187192 /// Stores the attributes for an attribute target,
188193 /// along with the tokens for that attribute target.
@@ -205,8 +210,8 @@ impl AttrTokenStream {
205210 . 0
206211 . iter ( )
207212 . 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 ( )
210215 }
211216 AttrTokenTree :: Delimited ( span, delim, stream) => {
212217 smallvec ! [ TokenTree :: Delimited ( * span, * delim, stream. to_tokenstream( ) ) , ]
@@ -307,21 +312,40 @@ pub struct AttributesData {
307312#[ derive( Clone , Debug , Default , Encodable , Decodable ) ]
308313pub struct TokenStream ( pub ( crate ) Lrc < Vec < TokenTree > > ) ;
309314
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`.
315317#[ 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 ,
325349}
326350
327351impl TokenStream {
@@ -336,7 +360,7 @@ impl TokenStream {
336360 let sp = match ( & ts, & next) {
337361 ( _, TokenTree :: Token ( Token { kind : token:: Comma , .. } , _) ) => continue ,
338362 (
339- TokenTree :: Token ( token_left, Spacing :: Alone ) ,
363+ TokenTree :: Token ( token_left, FollowedBy :: Space | FollowedBy :: Other ) ,
340364 TokenTree :: Token ( token_right, _) ,
341365 ) if ( ( token_left. is_ident ( ) && !token_left. is_reserved_ident ( ) )
342366 || token_left. is_lit ( ) )
@@ -349,7 +373,7 @@ impl TokenStream {
349373 _ => continue ,
350374 } ;
351375 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) ;
353377 suggestion = Some ( ( pos, comma, sp) ) ;
354378 }
355379 }
@@ -425,14 +449,22 @@ impl TokenStream {
425449 self
426450 }
427451
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) ] )
431462 }
432463
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) ] )
436468 }
437469
438470 /// Create a token stream containing a single `Delimited`.
@@ -458,16 +490,16 @@ impl TokenStream {
458490 pub fn from_nonterminal_ast ( nt : & Nonterminal ) -> TokenStream {
459491 match nt {
460492 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 )
462494 }
463495 Nonterminal :: NtLifetime ( ident) => {
464- TokenStream :: token_alone ( token:: Lifetime ( ident. name ) , ident. span )
496+ TokenStream :: token_fby_space ( token:: Lifetime ( ident. name ) , ident. span )
465497 }
466498 Nonterminal :: NtItem ( item) => TokenStream :: from_ast ( item) ,
467499 Nonterminal :: NtBlock ( block) => TokenStream :: from_ast ( block) ,
468500 Nonterminal :: NtStmt ( stmt) if let StmtKind :: Empty = stmt. kind => {
469501 // FIXME: Properly collect tokens for empty statements.
470- TokenStream :: token_alone ( token:: Semi , stmt. span )
502+ TokenStream :: token_fby_space ( token:: Semi , stmt. span )
471503 }
472504 Nonterminal :: NtStmt ( stmt) => TokenStream :: from_ast ( stmt) ,
473505 Nonterminal :: NtPat ( pat) => TokenStream :: from_ast ( pat) ,
@@ -479,23 +511,23 @@ impl TokenStream {
479511 }
480512 }
481513
482- fn flatten_token ( token : & Token , spacing : Spacing ) -> TokenTree {
514+ fn flatten_token ( token : & Token , fby : FollowedBy ) -> TokenTree {
483515 match & token. kind {
484516 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 )
486518 }
487519 token:: Interpolated ( nt) => TokenTree :: Delimited (
488520 DelimSpan :: from_single ( token. span ) ,
489521 Delimiter :: Invisible ,
490522 TokenStream :: from_nonterminal_ast ( nt) . flattened ( ) ,
491523 ) ,
492- _ => TokenTree :: Token ( token. clone ( ) , spacing ) ,
524+ _ => TokenTree :: Token ( token. clone ( ) , fby ) ,
493525 }
494526 }
495527
496528 fn flatten_token_tree ( tree : & TokenTree ) -> TokenTree {
497529 match tree {
498- TokenTree :: Token ( token, spacing ) => TokenStream :: flatten_token ( token, * spacing ) ,
530+ TokenTree :: Token ( token, fby ) => TokenStream :: flatten_token ( token, * fby ) ,
499531 TokenTree :: Delimited ( span, delim, tts) => {
500532 TokenTree :: Delimited ( * span, * delim, tts. flattened ( ) )
501533 }
@@ -521,13 +553,13 @@ impl TokenStream {
521553 // If `vec` is not empty, try to glue `tt` onto its last token. The return
522554 // value indicates if gluing took place.
523555 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
526558 && let Some ( glued_tok) = last_tok. glue ( tok)
527559 {
528560 // ...then overwrite the last token tree in `vec` with the
529561 // 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 ) ;
531563 true
532564 } else {
533565 false
@@ -583,7 +615,7 @@ impl TokenStream {
583615 match tt {
584616 & TokenTree :: Token (
585617 Token { kind : token:: DocComment ( _, attr_style, data) , span } ,
586- _spacing ,
618+ _fby ,
587619 ) => {
588620 let desugared = desugared_tts ( attr_style, data, span) ;
589621 let desugared_len = desugared. len ( ) ;
@@ -630,9 +662,9 @@ impl TokenStream {
630662 delim_span,
631663 Delimiter :: Bracket ,
632664 [
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 (
636668 TokenKind :: lit ( token:: StrRaw ( num_of_hashes) , data, None ) ,
637669 span,
638670 ) ,
@@ -643,12 +675,12 @@ impl TokenStream {
643675
644676 if attr_style == AttrStyle :: Inner {
645677 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) ,
648680 body,
649681 ]
650682 } else {
651- vec ! [ TokenTree :: token_alone ( token:: Pound , span) , body]
683+ vec ! [ TokenTree :: token_fby_space ( token:: Pound , span) , body]
652684 }
653685 }
654686 }
0 commit comments