@@ -107,7 +107,9 @@ impl Lit {
107
107
/// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation.
108
108
pub fn from_token ( token : & Token ) -> Option < Lit > {
109
109
match token. uninterpolate ( ) . kind {
110
- Ident ( name, false ) if name. is_bool_lit ( ) => Some ( Lit :: new ( Bool , name, None ) ) ,
110
+ Ident ( name, IdentKind :: Default ) if name. is_bool_lit ( ) => {
111
+ Some ( Lit :: new ( Bool , name, None ) )
112
+ }
111
113
Literal ( token_lit) => Some ( token_lit) ,
112
114
Interpolated ( ref nt)
113
115
if let NtExpr ( expr) | NtLiteral ( expr) = & nt. 0
@@ -183,8 +185,8 @@ impl LitKind {
183
185
}
184
186
}
185
187
186
- pub fn ident_can_begin_expr ( name : Symbol , span : Span , is_raw : bool ) -> bool {
187
- let ident_token = Token :: new ( Ident ( name, is_raw ) , span) ;
188
+ pub fn ident_can_begin_expr ( name : Symbol , span : Span , kind : IdentKind ) -> bool {
189
+ let ident_token = Token :: new ( Ident ( name, kind ) , span) ;
188
190
189
191
!ident_token. is_reserved_ident ( )
190
192
|| ident_token. is_path_segment_keyword ( )
@@ -212,15 +214,37 @@ pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool {
212
214
kw:: Static ,
213
215
]
214
216
. contains ( & name)
217
+ || kind == IdentKind :: Keyword
215
218
}
216
219
217
- fn ident_can_begin_type ( name : Symbol , span : Span , is_raw : bool ) -> bool {
218
- let ident_token = Token :: new ( Ident ( name, is_raw ) , span) ;
220
+ fn ident_can_begin_type ( name : Symbol , span : Span , kind : IdentKind ) -> bool {
221
+ let ident_token = Token :: new ( Ident ( name, kind ) , span) ;
219
222
220
223
!ident_token. is_reserved_ident ( )
221
224
|| ident_token. is_path_segment_keyword ( )
222
225
|| [ kw:: Underscore , kw:: For , kw:: Impl , kw:: Fn , kw:: Unsafe , kw:: Extern , kw:: Typeof , kw:: Dyn ]
223
226
. contains ( & name)
227
+ || kind == IdentKind :: Keyword
228
+ }
229
+
230
+ #[ derive( Clone , Copy , PartialEq , Eq , Debug , HashStable_Generic , Encodable , Decodable ) ]
231
+ pub enum IdentKind {
232
+ /// The usual identifiers (or, depending on the context, keywords): `v`, `union`, `await`, `loop`.
233
+ Default ,
234
+ /// Raw identifiers: `r#just_an_ident`, `r#loop`.
235
+ Raw ,
236
+ /// Forced keywords: `k#break`, `k#await`, `k#some_new_experimental_keyword`.
237
+ Keyword ,
238
+ }
239
+
240
+ impl IdentKind {
241
+ pub fn prefix ( self ) -> Option < & ' static str > {
242
+ match self {
243
+ IdentKind :: Default => None ,
244
+ IdentKind :: Raw => Some ( "r#" ) ,
245
+ IdentKind :: Keyword => Some ( "k#" ) ,
246
+ }
247
+ }
224
248
}
225
249
226
250
// SAFETY: due to the `Clone` impl below, all fields of all variants other than
@@ -298,10 +322,7 @@ pub enum TokenKind {
298
322
/// Do not forget about `NtIdent` when you want to match on identifiers.
299
323
/// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to
300
324
/// treat regular and interpolated identifiers in the same way.
301
- Ident ( Symbol , /* is_raw */ bool ) ,
302
-
303
- /// A `k#ident` keyword
304
- Keyword ( Symbol ) ,
325
+ Ident ( Symbol , IdentKind ) ,
305
326
306
327
/// Lifetime identifier token.
307
328
/// Do not forget about `NtLifetime` when you want to match on lifetime identifiers.
@@ -415,7 +436,13 @@ impl Token {
415
436
416
437
/// Recovers a `Token` from an `Ident`. This creates a raw identifier if necessary.
417
438
pub fn from_ast_ident ( ident : Ident ) -> Self {
418
- Token :: new ( Ident ( ident. name , ident. is_raw_guess ( ) ) , ident. span )
439
+ Token :: new (
440
+ Ident (
441
+ ident. name ,
442
+ if ident. is_raw_guess ( ) { IdentKind :: Raw } else { IdentKind :: Default } ,
443
+ ) ,
444
+ ident. span ,
445
+ )
419
446
}
420
447
421
448
/// For interpolated tokens, returns a span of the fragment to which the interpolated
@@ -442,7 +469,7 @@ impl Token {
442
469
| ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote => true ,
443
470
444
471
OpenDelim ( ..) | CloseDelim ( ..) | Literal ( ..) | DocComment ( ..) | Ident ( ..)
445
- | Keyword ( .. ) | Lifetime ( ..) | Interpolated ( ..) | Eof => false ,
472
+ | Lifetime ( ..) | Interpolated ( ..) | Eof => false ,
446
473
}
447
474
}
448
475
@@ -571,7 +598,7 @@ impl Token {
571
598
pub fn can_begin_literal_maybe_minus ( & self ) -> bool {
572
599
match self . uninterpolate ( ) . kind {
573
600
Literal ( ..) | BinOp ( Minus ) => true ,
574
- Ident ( name, false ) if name. is_bool_lit ( ) => true ,
601
+ Ident ( name, IdentKind :: Default ) if name. is_bool_lit ( ) => true ,
575
602
Interpolated ( ref nt) => match & nt. 0 {
576
603
NtLiteral ( _) => true ,
577
604
NtExpr ( e) => match & e. kind {
@@ -606,10 +633,10 @@ impl Token {
606
633
607
634
/// Returns an identifier if this token is an identifier.
608
635
#[ inline]
609
- pub fn ident ( & self ) -> Option < ( Ident , /* is_raw */ bool ) > {
636
+ pub fn ident ( & self ) -> Option < ( Ident , IdentKind ) > {
610
637
// We avoid using `Token::uninterpolate` here because it's slow.
611
638
match & self . kind {
612
- & Ident ( name, is_raw ) => Some ( ( Ident :: new ( name, self . span ) , is_raw ) ) ,
639
+ & Ident ( name, kind ) => Some ( ( Ident :: new ( name, self . span ) , kind ) ) ,
613
640
Interpolated ( nt) => match & nt. 0 {
614
641
NtIdent ( ident, is_raw) => Some ( ( * ident, * is_raw) ) ,
615
642
_ => None ,
@@ -702,46 +729,46 @@ impl Token {
702
729
703
730
/// Returns `true` if the token is a given keyword, `kw`.
704
731
pub fn is_keyword ( & self , kw : Symbol ) -> bool {
705
- self . is_non_raw_ident_where ( |id| id. name == kw)
732
+ self . is_keywordable_ident_where ( |id| id. name == kw)
706
733
}
707
734
708
735
/// Returns `true` if the token is a given keyword, `kw` or if `case` is `Insensitive` and this token is an identifier equal to `kw` ignoring the case.
709
736
pub fn is_keyword_case ( & self , kw : Symbol , case : Case ) -> bool {
710
737
self . is_keyword ( kw)
711
738
|| ( case == Case :: Insensitive
712
- && self . is_non_raw_ident_where ( |id| {
739
+ && self . is_keywordable_ident_where ( |id| {
713
740
id. name . as_str ( ) . to_lowercase ( ) == kw. as_str ( ) . to_lowercase ( )
714
741
} ) )
715
742
}
716
743
717
744
pub fn is_path_segment_keyword ( & self ) -> bool {
718
- self . is_non_raw_ident_where ( Ident :: is_path_segment_keyword)
745
+ self . is_keywordable_ident_where ( Ident :: is_path_segment_keyword)
719
746
}
720
747
721
748
/// Returns true for reserved identifiers used internally for elided lifetimes,
722
749
/// unnamed method parameters, crate root module, error recovery etc.
723
750
pub fn is_special_ident ( & self ) -> bool {
724
- self . is_non_raw_ident_where ( Ident :: is_special)
751
+ self . is_keywordable_ident_where ( Ident :: is_special)
725
752
}
726
753
727
754
/// Returns `true` if the token is a keyword used in the language.
728
755
pub fn is_used_keyword ( & self ) -> bool {
729
- self . is_non_raw_ident_where ( Ident :: is_used_keyword)
756
+ self . is_keywordable_ident_where ( Ident :: is_used_keyword)
730
757
}
731
758
732
759
/// Returns `true` if the token is a keyword reserved for possible future use.
733
760
pub fn is_unused_keyword ( & self ) -> bool {
734
- self . is_non_raw_ident_where ( Ident :: is_unused_keyword)
761
+ self . is_keywordable_ident_where ( Ident :: is_unused_keyword)
735
762
}
736
763
737
764
/// Returns `true` if the token is either a special identifier or a keyword.
738
765
pub fn is_reserved_ident ( & self ) -> bool {
739
- self . is_non_raw_ident_where ( Ident :: is_reserved)
766
+ self . is_keywordable_ident_where ( Ident :: is_reserved)
740
767
}
741
768
742
769
/// Returns `true` if the token is the identifier `true` or `false`.
743
770
pub fn is_bool_lit ( & self ) -> bool {
744
- self . is_non_raw_ident_where ( |id| id. name . is_bool_lit ( ) )
771
+ self . is_keywordable_ident_where ( |id| id. name . is_bool_lit ( ) )
745
772
}
746
773
747
774
pub fn is_numeric_lit ( & self ) -> bool {
@@ -757,9 +784,9 @@ impl Token {
757
784
}
758
785
759
786
/// Returns `true` if the token is a non-raw identifier for which `pred` holds.
760
- pub fn is_non_raw_ident_where ( & self , pred : impl FnOnce ( Ident ) -> bool ) -> bool {
787
+ pub fn is_keywordable_ident_where ( & self , pred : impl FnOnce ( Ident ) -> bool ) -> bool {
761
788
match self . ident ( ) {
762
- Some ( ( id, false ) ) => pred ( id) ,
789
+ Some ( ( id, IdentKind :: Default | IdentKind :: Keyword ) ) => pred ( id) ,
763
790
_ => false ,
764
791
}
765
792
}
@@ -810,13 +837,13 @@ impl Token {
810
837
_ => return None ,
811
838
} ,
812
839
SingleQuote => match joint. kind {
813
- Ident ( name, false ) => Lifetime ( Symbol :: intern ( & format ! ( "'{name}" ) ) ) ,
840
+ Ident ( name, IdentKind :: Default ) => Lifetime ( Symbol :: intern ( & format ! ( "'{name}" ) ) ) ,
814
841
_ => return None ,
815
842
} ,
816
843
817
844
Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq ( ..) | At | DotDotDot
818
845
| DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar
819
- | Question | OpenDelim ( ..) | CloseDelim ( ..) | Literal ( ..) | Ident ( ..) | Keyword ( .. )
846
+ | Question | OpenDelim ( ..) | CloseDelim ( ..) | Literal ( ..) | Ident ( ..)
820
847
| Lifetime ( ..) | Interpolated ( ..) | DocComment ( ..) | Eof => return None ,
821
848
} ;
822
849
@@ -840,7 +867,7 @@ pub enum Nonterminal {
840
867
NtPat ( P < ast:: Pat > ) ,
841
868
NtExpr ( P < ast:: Expr > ) ,
842
869
NtTy ( P < ast:: Ty > ) ,
843
- NtIdent ( Ident , /* is_raw */ bool ) ,
870
+ NtIdent ( Ident , IdentKind ) ,
844
871
NtLifetime ( Ident ) ,
845
872
NtLiteral ( P < ast:: Expr > ) ,
846
873
/// Stuff inside brackets for attributes
0 commit comments