11use rustc_ast:: ptr:: P ;
2- use rustc_ast:: token:: { self , Delimiter , Nonterminal :: * , NonterminalKind , Token } ;
2+ use rustc_ast:: token:: { self , Delimiter , InvisibleSource , Nonterminal :: * , NonterminalKind , Token } ;
33use rustc_ast:: HasTokens ;
44use rustc_ast_pretty:: pprust;
55use rustc_data_structures:: sync:: Lrc ;
@@ -20,7 +20,30 @@ impl<'a> Parser<'a> {
2020 #[ inline]
2121 pub fn nonterminal_may_begin_with ( kind : NonterminalKind , token : & Token ) -> bool {
2222 /// Checks whether the non-terminal may contain a single (non-keyword) identifier.
23- fn may_be_ident ( nt : & token:: Nonterminal ) -> bool {
23+ fn may_be_ident ( kind : NonterminalKind ) -> bool {
24+ use NonterminalKind :: * ;
25+ match kind {
26+ Stmt
27+ | PatParam { .. }
28+ | PatWithOr
29+ | Expr
30+ | Ty
31+ | Ident
32+ | Literal // `true`, `false`
33+ | Meta
34+ | Path => true ,
35+
36+ Item
37+ | Block
38+ | Vis
39+ | Lifetime => false ,
40+
41+ TT => unreachable ! ( ) ,
42+ }
43+ }
44+
45+ /// Old variant of `may_be_ident`, being phased out.
46+ fn nt_may_be_ident ( nt : & token:: Nonterminal ) -> bool {
2447 match nt {
2548 NtStmt ( _)
2649 | NtPat ( _)
@@ -50,8 +73,11 @@ impl<'a> Parser<'a> {
5073 NonterminalKind :: Ident => get_macro_ident ( token) . is_some ( ) ,
5174 NonterminalKind :: Literal => token. can_begin_literal_maybe_minus ( ) ,
5275 NonterminalKind :: Vis => match token. kind {
53- // The follow-set of :vis + "priv" keyword + interpolated
54- token:: Comma | token:: Ident ( ..) | token:: Interpolated ( ..) => true ,
76+ // The follow-set of :vis + "priv" keyword + interpolated/metavar-expansion
77+ token:: Comma
78+ | token:: Ident ( ..)
79+ | token:: Interpolated ( ..)
80+ | token:: OpenDelim ( Delimiter :: Invisible ( InvisibleSource :: MetaVar ( _) ) ) => true ,
5581 _ => token. can_begin_type ( ) ,
5682 } ,
5783 NonterminalKind :: Block => match & token. kind {
@@ -61,11 +87,30 @@ impl<'a> Parser<'a> {
6187 NtItem ( _) | NtPat ( _) | NtTy ( _) | NtIdent ( ..) | NtMeta ( _) | NtPath ( _)
6288 | NtVis ( _) => false ,
6389 } ,
90+ token:: OpenDelim ( Delimiter :: Invisible ( InvisibleSource :: MetaVar ( k) ) ) => match k {
91+ NonterminalKind :: Block
92+ | NonterminalKind :: Lifetime
93+ | NonterminalKind :: Stmt
94+ | NonterminalKind :: Expr
95+ | NonterminalKind :: Literal => true ,
96+ NonterminalKind :: Item
97+ | NonterminalKind :: PatParam { .. }
98+ | NonterminalKind :: PatWithOr
99+ | NonterminalKind :: Ty
100+ | NonterminalKind :: Ident
101+ | NonterminalKind :: Meta
102+ | NonterminalKind :: Path
103+ | NonterminalKind :: Vis => false ,
104+ NonterminalKind :: TT => unreachable ! ( ) ,
105+ } ,
64106 _ => false ,
65107 } ,
66108 NonterminalKind :: Path | NonterminalKind :: Meta => match & token. kind {
67109 token:: ModSep | token:: Ident ( ..) => true ,
68- token:: Interpolated ( nt) => may_be_ident ( nt) ,
110+ token:: Interpolated ( nt) => nt_may_be_ident ( nt) ,
111+ token:: OpenDelim ( Delimiter :: Invisible ( InvisibleSource :: MetaVar ( kind) ) ) => {
112+ may_be_ident ( * kind)
113+ }
69114 _ => false ,
70115 } ,
71116 NonterminalKind :: PatParam { .. } | NonterminalKind :: PatWithOr => {
@@ -84,7 +129,10 @@ impl<'a> Parser<'a> {
84129 token:: BinOp ( token:: Shl ) => true , // path (double UFCS)
85130 // leading vert `|` or-pattern
86131 token:: BinOp ( token:: Or ) => matches ! ( kind, NonterminalKind :: PatWithOr ) ,
87- token:: Interpolated ( nt) => may_be_ident ( nt) ,
132+ token:: Interpolated ( nt) => nt_may_be_ident ( nt) ,
133+ token:: OpenDelim ( Delimiter :: Invisible ( InvisibleSource :: MetaVar ( kind) ) ) => {
134+ may_be_ident ( * kind)
135+ }
88136 _ => false ,
89137 }
90138 }
@@ -93,6 +141,9 @@ impl<'a> Parser<'a> {
93141 token:: Interpolated ( nt) => {
94142 matches ! ( * * nt, NtLifetime ( _) )
95143 }
144+ token:: OpenDelim ( Delimiter :: Invisible ( InvisibleSource :: MetaVar (
145+ NonterminalKind :: Lifetime ,
146+ ) ) ) => true ,
96147 _ => false ,
97148 } ,
98149 NonterminalKind :: TT | NonterminalKind :: Item | NonterminalKind :: Stmt => {
0 commit comments