@@ -40,7 +40,7 @@ pub enum BinOpToken {
40
40
#[ derive( Copy , Clone , Debug , PartialEq , Eq , Encodable , Decodable , Hash , HashStable_Generic ) ]
41
41
pub enum InvisibleOrigin {
42
42
// From the expansion of a metavariable in a declarative macro.
43
- MetaVar ( NonterminalKind ) ,
43
+ MetaVar ( MetaVarKind ) ,
44
44
45
45
// Converted from `proc_macro::Delimiter` in
46
46
// `proc_macro::Delimiter::to_internal`, i.e. returned by a proc macro.
@@ -51,6 +51,54 @@ pub enum InvisibleOrigin {
51
51
FlattenToken ,
52
52
}
53
53
54
+ /// Annoyingly similar to `NonterminalKind`, but the slightly differences are important.
55
+ #[ derive( Debug , Copy , Clone , PartialEq , Eq , Encodable , Decodable , Hash , HashStable_Generic ) ]
56
+ pub enum MetaVarKind {
57
+ Item ,
58
+ Block ,
59
+ Stmt ,
60
+ Pat ( NtPatKind ) ,
61
+ Expr {
62
+ kind : NtExprKind ,
63
+ // This field is needed for `Token::can_begin_literal_maybe_minus`.
64
+ can_begin_literal_maybe_minus : bool ,
65
+ // This field is needed for `Token::can_begin_string_literal`.
66
+ can_begin_string_literal : bool ,
67
+ } ,
68
+ Ty ,
69
+ Ident ,
70
+ Lifetime ,
71
+ Literal ,
72
+ Meta ,
73
+ Path ,
74
+ Vis ,
75
+ TT ,
76
+ }
77
+
78
+ impl fmt:: Display for MetaVarKind {
79
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
80
+ use MetaVarKind :: * ;
81
+ let sym = match self {
82
+ Item => sym:: item,
83
+ Block => sym:: block,
84
+ Stmt => sym:: stmt,
85
+ Pat ( PatParam { inferred : true } | PatWithOr ) => sym:: pat,
86
+ Pat ( PatParam { inferred : false } ) => sym:: pat_param,
87
+ Expr { kind : Expr2021 { inferred : true } | Expr , .. } => sym:: expr,
88
+ Expr { kind : Expr2021 { inferred : false } , .. } => sym:: expr_2021,
89
+ Ty => sym:: ty,
90
+ Ident => sym:: ident,
91
+ Lifetime => sym:: lifetime,
92
+ Literal => sym:: literal,
93
+ Meta => sym:: meta,
94
+ Path => sym:: path,
95
+ Vis => sym:: vis,
96
+ TT => sym:: tt,
97
+ } ;
98
+ write ! ( f, "{}" , sym)
99
+ }
100
+ }
101
+
54
102
/// Describes how a sequence of token trees is delimited.
55
103
/// Cannot use `proc_macro::Delimiter` directly because this
56
104
/// structure should implement some additional traits.
@@ -138,15 +186,17 @@ impl Lit {
138
186
match token. uninterpolate ( ) . kind {
139
187
Ident ( name, IdentIsRaw :: No ) if name. is_bool_lit ( ) => Some ( Lit :: new ( Bool , name, None ) ) ,
140
188
Literal ( token_lit) => Some ( token_lit) ,
141
- OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar ( NonterminalKind :: Literal ) ) ) => {
189
+ OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar ( MetaVarKind :: Literal ) ) ) => {
142
190
panic ! ( "njn: FROM_TOKEN (1)" ) ;
143
191
// if let NtExpr(expr) | NtLiteral(expr) = &**nt
144
192
// && let ast::ExprKind::Lit(token_lit) = expr.kind =>
145
193
// {
146
194
// Some(token_lit)
147
195
// }
148
196
}
149
- OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar ( NonterminalKind :: Expr ( _) ) ) ) => {
197
+ OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar ( MetaVarKind :: Expr {
198
+ ..
199
+ } ) ) ) => {
150
200
panic ! ( "njn: FROM_TOKEN (2)" ) ;
151
201
// if let NtExpr(expr) | NtLiteral(expr) = &**nt
152
202
// && let ast::ExprKind::Lit(token_lit) = expr.kind =>
@@ -511,10 +561,10 @@ impl Token {
511
561
Lifetime ( ..) | // labeled loop
512
562
Pound => true , // expression attributes
513
563
OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar (
514
- NonterminalKind :: Block |
515
- NonterminalKind :: Expr ( _ ) |
516
- NonterminalKind :: Literal |
517
- NonterminalKind :: Path
564
+ MetaVarKind :: Block |
565
+ MetaVarKind :: Expr { .. } |
566
+ MetaVarKind :: Literal |
567
+ MetaVarKind :: Path
518
568
) ) ) => true ,
519
569
_ => false ,
520
570
}
@@ -537,10 +587,10 @@ impl Token {
537
587
| Lt | BinOp ( Shl ) // associated path
538
588
| PathSep => true , // global path
539
589
OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar (
540
- NonterminalKind :: Block |
541
- NonterminalKind :: Pat ( _) |
542
- NonterminalKind :: Path |
543
- NonterminalKind :: Literal
590
+ MetaVarKind :: Block |
591
+ MetaVarKind :: Pat ( _) |
592
+ MetaVarKind :: Path |
593
+ MetaVarKind :: Literal
544
594
) ) ) => true ,
545
595
_ => false ,
546
596
}
@@ -562,8 +612,8 @@ impl Token {
562
612
Lt | BinOp ( Shl ) | // associated path
563
613
PathSep => true , // global path
564
614
OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar (
565
- NonterminalKind :: Ty |
566
- NonterminalKind :: Path
615
+ MetaVarKind :: Ty |
616
+ MetaVarKind :: Path
567
617
) ) ) => true ,
568
618
// For anonymous structs or unions, which only appear in specific positions
569
619
// (type of struct fields or union fields), we don't consider them as regular types
@@ -577,7 +627,7 @@ impl Token {
577
627
OpenDelim ( Delimiter :: Brace ) | Literal ( ..) | BinOp ( Minus ) => true ,
578
628
Ident ( name, IdentIsRaw :: No ) if name. is_bool_lit ( ) => true ,
579
629
OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar (
580
- NonterminalKind :: Expr ( _ ) | NonterminalKind :: Block | NonterminalKind :: Literal ,
630
+ MetaVarKind :: Expr { .. } | MetaVarKind :: Block | MetaVarKind :: Literal ,
581
631
) ) ) => true ,
582
632
_ => false ,
583
633
}
@@ -625,42 +675,25 @@ impl Token {
625
675
match self . uninterpolate ( ) . kind {
626
676
Literal ( ..) | BinOp ( Minus ) => true ,
627
677
Ident ( name, IdentIsRaw :: No ) if name. is_bool_lit ( ) => true ,
628
- // njn: fix up
629
- // Interpolated(ref nt) => match &**nt {
630
- // NtLiteral(_) => true,
631
- // NtExpr(e) => match &e.kind {
632
- // ast::ExprKind::Lit(_) => true,
633
- // ast::ExprKind::Unary(ast::UnOp::Neg, e) => {
634
- // matches!(&e.kind, ast::ExprKind::Lit(_))
635
- // }
636
- // _ => false,
637
- // },
638
- // _ => false,
639
- // },
640
- // njn: too simple compared to what's above?
641
- OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar (
642
- NonterminalKind :: Literal | NonterminalKind :: Expr ( _) ,
643
- ) ) ) => true ,
678
+ OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar ( mv_kind) ) ) => match mv_kind {
679
+ MetaVarKind :: Literal => true ,
680
+ MetaVarKind :: Expr { can_begin_literal_maybe_minus, .. } => {
681
+ can_begin_literal_maybe_minus
682
+ }
683
+ _ => false ,
684
+ } ,
644
685
_ => false ,
645
686
}
646
687
}
647
688
648
689
pub fn can_begin_string_literal ( & self ) -> bool {
649
690
match self . uninterpolate ( ) . kind {
650
691
Literal ( ..) => true ,
651
- // njn: fix up
652
- // Interpolated(ref nt) => match &**nt {
653
- // NtLiteral(_) => true,
654
- // NtExpr(e) => match &e.kind {
655
- // ast::ExprKind::Lit(_) => true,
656
- // _ => false,
657
- // },
658
- // _ => false,
659
- // },
660
- // njn: too simple compared to what's above?
661
- OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar (
662
- NonterminalKind :: Literal | NonterminalKind :: Expr ( _) ,
663
- ) ) ) => true ,
692
+ OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar ( mv_kind) ) ) => match mv_kind {
693
+ MetaVarKind :: Literal => true ,
694
+ MetaVarKind :: Expr { can_begin_string_literal, .. } => can_begin_string_literal,
695
+ _ => false ,
696
+ } ,
664
697
_ => false ,
665
698
}
666
699
}
@@ -715,24 +748,24 @@ impl Token {
715
748
self . ident ( ) . is_some_and ( |( ident, _) | ident. name == name)
716
749
}
717
750
718
- /// Would `maybe_reparse_metavar_expr ` in `parser.rs` return `Ok(..)`?
751
+ /// Would `eat_metavar_expr ` in `parser.rs` return `Ok(..)`?
719
752
/// That is, is this a pre-parsed expression dropped into the token stream
720
753
/// (which happens while parsing the result of macro expansion)?
721
754
pub fn is_metavar_expr ( & self ) -> bool {
722
755
matches ! (
723
756
self . is_metavar_seq( ) ,
724
757
Some (
725
- NonterminalKind :: Expr ( _ )
726
- | NonterminalKind :: Literal
727
- | NonterminalKind :: Path
728
- | NonterminalKind :: Block
758
+ MetaVarKind :: Expr { .. }
759
+ | MetaVarKind :: Literal
760
+ | MetaVarKind :: Path
761
+ | MetaVarKind :: Block
729
762
)
730
763
)
731
764
}
732
765
733
766
/// Are we at a block from a metavar (`$b:block`)?
734
767
pub fn is_metavar_block ( & self ) -> bool {
735
- matches ! ( self . is_metavar_seq( ) , Some ( NonterminalKind :: Block ) )
768
+ matches ! ( self . is_metavar_seq( ) , Some ( MetaVarKind :: Block ) )
736
769
}
737
770
738
771
/// Returns `true` if the token is either the `mut` or `const` keyword.
@@ -747,7 +780,7 @@ impl Token {
747
780
pub fn is_path_start ( & self ) -> bool {
748
781
self == & PathSep
749
782
|| self . is_qpath_start ( )
750
- || matches ! ( self . is_metavar_seq( ) , Some ( NonterminalKind :: Path ) )
783
+ || matches ! ( self . is_metavar_seq( ) , Some ( MetaVarKind :: Path ) )
751
784
|| self . is_path_segment_keyword ( )
752
785
|| self . is_ident ( ) && !self . is_reserved_ident ( )
753
786
}
@@ -819,7 +852,7 @@ impl Token {
819
852
820
853
/// Is this an invisible open delimiter at the start of a token sequence
821
854
/// from an expanded metavar?
822
- pub fn is_metavar_seq ( & self ) -> Option < NonterminalKind > {
855
+ pub fn is_metavar_seq ( & self ) -> Option < MetaVarKind > {
823
856
match self . kind {
824
857
OpenDelim ( Delimiter :: Invisible ( InvisibleOrigin :: MetaVar ( kind) ) ) => Some ( kind) ,
825
858
_ => None ,
0 commit comments