@@ -41,8 +41,7 @@ pub enum BinOpToken {
41
41
/// structure should implement some additional traits.
42
42
/// The `None` variant is also renamed to `Invisible` to be
43
43
/// 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 ) ]
46
45
pub enum Delimiter {
47
46
/// `( ... )`
48
47
Parenthesis ,
@@ -56,7 +55,36 @@ pub enum Delimiter {
56
55
/// `$var * 3` where `$var` is `1 + 2`.
57
56
/// Invisible delimiters are not directly writable in normal Rust code except as comments.
58
57
/// 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
+ }
60
88
}
61
89
62
90
#[ derive( Clone , Copy , PartialEq , Encodable , Decodable , Debug , HashStable_Generic ) ]
@@ -246,7 +274,9 @@ pub enum TokenKind {
246
274
/// - It requires special handling in a bunch of places in the parser.
247
275
/// - It prevents `Token` from implementing `Copy`.
248
276
/// 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`.
250
280
Interpolated ( Lrc < Nonterminal > ) ,
251
281
252
282
/// A doc comment token.
@@ -377,7 +407,7 @@ impl Token {
377
407
match self . uninterpolate ( ) . kind {
378
408
Ident ( name, is_raw) =>
379
409
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
381
411
Literal ( ..) | // literal
382
412
Not | // operator not
383
413
BinOp ( Minus ) | // unary minus
@@ -392,7 +422,6 @@ impl Token {
392
422
Lifetime ( ..) | // labeled loop
393
423
Pound => true , // expression attributes
394
424
Interpolated ( ref nt) => matches ! ( * * nt, NtLiteral ( ..) |
395
- NtExpr ( ..) |
396
425
NtBlock ( ..) |
397
426
NtPath ( ..) ) ,
398
427
_ => false ,
@@ -422,8 +451,8 @@ impl Token {
422
451
/// Returns `true` if the token can appear at the start of a const param.
423
452
pub fn can_begin_const_arg ( & self ) -> bool {
424
453
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 ( ..) ) ,
427
456
_ => self . can_begin_literal_maybe_minus ( ) ,
428
457
}
429
458
}
@@ -448,21 +477,25 @@ impl Token {
448
477
/// In other words, would this token be a valid start of `parse_literal_maybe_minus`?
449
478
///
450
479
/// Keep this in sync with and `Lit::from_token`, excluding unary negation.
480
+ // njn: ugh to that comment
451
481
pub fn can_begin_literal_maybe_minus ( & self ) -> bool {
452
482
match self . uninterpolate ( ) . kind {
453
483
Literal ( ..) | BinOp ( Minus ) => true ,
454
484
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
466
499
_ => false ,
467
500
}
468
501
}
@@ -536,19 +569,6 @@ impl Token {
536
569
false
537
570
}
538
571
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
-
552
572
// Is the token an interpolated block (`$b:block`)?
553
573
pub fn is_whole_block ( & self ) -> bool {
554
574
if let Interpolated ( ref nt) = self . kind && let NtBlock ( ..) = * * nt {
@@ -690,14 +710,16 @@ impl PartialEq<TokenKind> for Token {
690
710
}
691
711
}
692
712
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.
693
716
#[ derive( Clone , Encodable , Decodable ) ]
694
717
/// For interpolation during macro expansion.
695
718
pub enum Nonterminal {
696
719
NtItem ( P < ast:: Item > ) ,
697
720
NtBlock ( P < ast:: Block > ) ,
698
721
NtStmt ( P < ast:: Stmt > ) ,
699
722
NtPat ( P < ast:: Pat > ) ,
700
- NtExpr ( P < ast:: Expr > ) ,
701
723
NtTy ( P < ast:: Ty > ) ,
702
724
NtIdent ( Ident , /* is_raw */ bool ) ,
703
725
NtLifetime ( Ident ) ,
@@ -797,7 +819,7 @@ impl Nonterminal {
797
819
NtBlock ( block) => block. span ,
798
820
NtStmt ( stmt) => stmt. span ,
799
821
NtPat ( pat) => pat. span ,
800
- NtExpr ( expr ) | NtLiteral ( expr) => expr. span ,
822
+ NtLiteral ( expr) => expr. span ,
801
823
NtTy ( ty) => ty. span ,
802
824
NtIdent ( ident, _) | NtLifetime ( ident) => ident. span ,
803
825
NtMeta ( attr_item) => attr_item. span ( ) ,
@@ -830,7 +852,6 @@ impl fmt::Debug for Nonterminal {
830
852
NtBlock ( ..) => f. pad ( "NtBlock(..)" ) ,
831
853
NtStmt ( ..) => f. pad ( "NtStmt(..)" ) ,
832
854
NtPat ( ..) => f. pad ( "NtPat(..)" ) ,
833
- NtExpr ( ..) => f. pad ( "NtExpr(..)" ) ,
834
855
NtTy ( ..) => f. pad ( "NtTy(..)" ) ,
835
856
NtIdent ( ..) => f. pad ( "NtIdent(..)" ) ,
836
857
NtLiteral ( ..) => f. pad ( "NtLiteral(..)" ) ,
0 commit comments