@@ -41,8 +41,7 @@ pub enum BinOpToken {
4141/// structure should implement some additional traits.
4242/// The `None` variant is also renamed to `Invisible` to be
4343/// less confusing and better convey the semantics.
44- #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
45- #[ derive( Encodable , Decodable , Hash , HashStable_Generic ) ]
44+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , Encodable , Decodable , Hash , HashStable_Generic ) ]
4645pub enum Delimiter {
4746 /// `( ... )`
4847 Parenthesis ,
@@ -56,7 +55,36 @@ pub enum Delimiter {
5655 /// `$var * 3` where `$var` is `1 + 2`.
5756 /// Invisible delimiters are not directly writable in normal Rust code except as comments.
5857 /// Therefore, they might not survive a roundtrip of a token stream through a string.
59- Invisible ,
58+ Invisible ( InvisibleSource ) ,
59+ }
60+
61+ // We are in the process of migrating interpolated nonterminals to
62+ // invisible-delimited token sequences. This enum will grow as `Nonterminal`
63+ // shrinks.
64+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , Encodable , Decodable , Hash , HashStable_Generic ) ]
65+ pub enum InvisibleSource {
66+ // From the expansion of a `expr` metavar in a declarative macro.
67+ ExprMv ,
68+ // Converted from `proc_macro::Delimiter`, i.e. returned by a proc macro.
69+ ProcMacro ,
70+ // Converted from `TokenKind::Interpolated` in `flatten_token`. Treated
71+ // similarly to `ProcMacro`.
72+ FlattenToken ,
73+ }
74+
75+ impl Delimiter {
76+ // Should the parser skip these delimeters? Only happens for certain kinds
77+ // of invisible delimiters. Eventually the answer should be `false` for all
78+ // kinds, whereupon this function can be removed.
79+ pub fn skip ( & self ) -> bool {
80+ match self {
81+ Delimiter :: Invisible ( src) => match src {
82+ InvisibleSource :: FlattenToken | InvisibleSource :: ProcMacro => true ,
83+ InvisibleSource :: ExprMv => false ,
84+ } ,
85+ Delimiter :: Parenthesis | Delimiter :: Bracket | Delimiter :: Brace => false ,
86+ }
87+ }
6088}
6189
6290#[ derive( Clone , Copy , PartialEq , Encodable , Decodable , Debug , HashStable_Generic ) ]
@@ -246,7 +274,9 @@ pub enum TokenKind {
246274 /// - It requires special handling in a bunch of places in the parser.
247275 /// - It prevents `Token` from implementing `Copy`.
248276 /// It adds complexity and likely slows things down. Please don't add new
249- /// occurrences of this token kind!
277+ /// occurrences of this token kind! See `InvisibleSource` for details on
278+ /// how it will be removed, and #96764 for potential speed benefits of
279+ /// making `Token` implement `Copy`.
250280 Interpolated ( Lrc < Nonterminal > ) ,
251281
252282 /// A doc comment token.
@@ -377,7 +407,7 @@ impl Token {
377407 match self . uninterpolate ( ) . kind {
378408 Ident ( name, is_raw) =>
379409 ident_can_begin_expr ( name, self . span , is_raw) , // value name or keyword
380- OpenDelim ( ..) | // tuple, array or block
410+ OpenDelim ( ..) | // tuple, array, block, or macro output
381411 Literal ( ..) | // literal
382412 Not | // operator not
383413 BinOp ( Minus ) | // unary minus
@@ -392,7 +422,6 @@ impl Token {
392422 Lifetime ( ..) | // labeled loop
393423 Pound => true , // expression attributes
394424 Interpolated ( ref nt) => matches ! ( * * nt, NtLiteral ( ..) |
395- NtExpr ( ..) |
396425 NtBlock ( ..) |
397426 NtPath ( ..) ) ,
398427 _ => false ,
@@ -422,8 +451,8 @@ impl Token {
422451 /// Returns `true` if the token can appear at the start of a const param.
423452 pub fn can_begin_const_arg ( & self ) -> bool {
424453 match self . kind {
425- OpenDelim ( Delimiter :: Brace ) => true ,
426- Interpolated ( ref nt) => matches ! ( * * nt, NtExpr ( .. ) | NtBlock ( ..) | NtLiteral ( ..) ) ,
454+ OpenDelim ( Delimiter :: Brace | Delimiter :: Invisible ( InvisibleSource :: ExprMv ) ) => true ,
455+ Interpolated ( ref nt) => matches ! ( * * nt, NtBlock ( ..) | NtLiteral ( ..) ) ,
427456 _ => self . can_begin_literal_maybe_minus ( ) ,
428457 }
429458 }
@@ -448,21 +477,25 @@ impl Token {
448477 /// In other words, would this token be a valid start of `parse_literal_maybe_minus`?
449478 ///
450479 /// Keep this in sync with and `Lit::from_token`, excluding unary negation.
480+ // njn: ugh to that comment
451481 pub fn can_begin_literal_maybe_minus ( & self ) -> bool {
452482 match self . uninterpolate ( ) . kind {
453483 Literal ( ..) | BinOp ( Minus ) => true ,
454484 Ident ( name, false ) if name. is_bool_lit ( ) => true ,
455- Interpolated ( ref nt) => match & * * nt {
456- NtLiteral ( _) => true ,
457- NtExpr ( e) => match & e. kind {
458- ast:: ExprKind :: Lit ( _) => true ,
459- ast:: ExprKind :: Unary ( ast:: UnOp :: Neg , e) => {
460- matches ! ( & e. kind, ast:: ExprKind :: Lit ( _) )
461- }
462- _ => false ,
463- } ,
464- _ => false ,
465- } ,
485+ OpenDelim ( Delimiter :: Invisible ( InvisibleSource :: ExprMv ) ) => true ,
486+ Interpolated ( ref nt) => matches ! ( * * nt, NtLiteral ( _) ) ,
487+ _ => false ,
488+ }
489+ }
490+
491+ // Can this token be a valid start of `parse_unsuffixed_literal`?
492+ pub fn can_begin_unsuffixed_literal ( & self ) -> bool {
493+ match self . uninterpolate ( ) . kind {
494+ Literal ( ..) => true ,
495+ Ident ( name, false ) if name. is_bool_lit ( ) => true ,
496+ OpenDelim ( Delimiter :: Invisible ( InvisibleSource :: ExprMv ) ) => true ,
497+ Interpolated ( ref nt) => matches ! ( * * nt, NtLiteral ( _) ) ,
498+ Dot => true , // not valid, but accepted for recovery
466499 _ => false ,
467500 }
468501 }
@@ -536,19 +569,6 @@ impl Token {
536569 false
537570 }
538571
539- /// Would `maybe_whole_expr` in `parser.rs` return `Ok(..)`?
540- /// That is, is this a pre-parsed expression dropped into the token stream
541- /// (which happens while parsing the result of macro expansion)?
542- pub fn is_whole_expr ( & self ) -> bool {
543- if let Interpolated ( ref nt) = self . kind
544- && let NtExpr ( _) | NtLiteral ( _) | NtPath ( _) | NtBlock ( _) = * * nt
545- {
546- return true ;
547- }
548-
549- false
550- }
551-
552572 // Is the token an interpolated block (`$b:block`)?
553573 pub fn is_whole_block ( & self ) -> bool {
554574 if let Interpolated ( ref nt) = self . kind && let NtBlock ( ..) = * * nt {
@@ -690,14 +710,16 @@ impl PartialEq<TokenKind> for Token {
690710 }
691711}
692712
713+ // We are in the process of migrating interpolated nonterminals to
714+ // invisible-delimited token sequences (e.g. #96724). This enum will shrink as
715+ // `InvisibleSource` grows.
693716#[ derive( Clone , Encodable , Decodable ) ]
694717/// For interpolation during macro expansion.
695718pub enum Nonterminal {
696719 NtItem ( P < ast:: Item > ) ,
697720 NtBlock ( P < ast:: Block > ) ,
698721 NtStmt ( P < ast:: Stmt > ) ,
699722 NtPat ( P < ast:: Pat > ) ,
700- NtExpr ( P < ast:: Expr > ) ,
701723 NtTy ( P < ast:: Ty > ) ,
702724 NtIdent ( Ident , /* is_raw */ bool ) ,
703725 NtLifetime ( Ident ) ,
@@ -797,7 +819,7 @@ impl Nonterminal {
797819 NtBlock ( block) => block. span ,
798820 NtStmt ( stmt) => stmt. span ,
799821 NtPat ( pat) => pat. span ,
800- NtExpr ( expr ) | NtLiteral ( expr) => expr. span ,
822+ NtLiteral ( expr) => expr. span ,
801823 NtTy ( ty) => ty. span ,
802824 NtIdent ( ident, _) | NtLifetime ( ident) => ident. span ,
803825 NtMeta ( attr_item) => attr_item. span ( ) ,
@@ -830,7 +852,6 @@ impl fmt::Debug for Nonterminal {
830852 NtBlock ( ..) => f. pad ( "NtBlock(..)" ) ,
831853 NtStmt ( ..) => f. pad ( "NtStmt(..)" ) ,
832854 NtPat ( ..) => f. pad ( "NtPat(..)" ) ,
833- NtExpr ( ..) => f. pad ( "NtExpr(..)" ) ,
834855 NtTy ( ..) => f. pad ( "NtTy(..)" ) ,
835856 NtIdent ( ..) => f. pad ( "NtIdent(..)" ) ,
836857 NtLiteral ( ..) => f. pad ( "NtLiteral(..)" ) ,
0 commit comments