@@ -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
@@ -580,7 +607,7 @@ impl Token {
580
607
pub fn can_begin_literal_maybe_minus ( & self ) -> bool {
581
608
match self . uninterpolate ( ) . kind {
582
609
Literal ( ..) | BinOp ( Minus ) => true ,
583
- Ident ( name, false ) if name. is_bool_lit ( ) => true ,
610
+ Ident ( name, IdentKind :: Default ) if name. is_bool_lit ( ) => true ,
584
611
Interpolated ( ref nt) => match & nt. 0 {
585
612
NtLiteral ( _) => true ,
586
613
NtExpr ( e) => match & e. kind {
@@ -615,10 +642,10 @@ impl Token {
615
642
616
643
/// Returns an identifier if this token is an identifier.
617
644
#[ inline]
618
- pub fn ident ( & self ) -> Option < ( Ident , /* is_raw */ bool ) > {
645
+ pub fn ident ( & self ) -> Option < ( Ident , IdentKind ) > {
619
646
// We avoid using `Token::uninterpolate` here because it's slow.
620
647
match & self . kind {
621
- & Ident ( name, is_raw ) => Some ( ( Ident :: new ( name, self . span ) , is_raw ) ) ,
648
+ & Ident ( name, kind ) => Some ( ( Ident :: new ( name, self . span ) , kind ) ) ,
622
649
Interpolated ( nt) => match & nt. 0 {
623
650
NtIdent ( ident, is_raw) => Some ( ( * ident, * is_raw) ) ,
624
651
_ => None ,
@@ -711,46 +738,46 @@ impl Token {
711
738
712
739
/// Returns `true` if the token is a given keyword, `kw`.
713
740
pub fn is_keyword ( & self , kw : Symbol ) -> bool {
714
- self . is_non_raw_ident_where ( |id| id. name == kw)
741
+ self . is_keywordable_ident_where ( |id| id. name == kw)
715
742
}
716
743
717
744
/// 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.
718
745
pub fn is_keyword_case ( & self , kw : Symbol , case : Case ) -> bool {
719
746
self . is_keyword ( kw)
720
747
|| ( case == Case :: Insensitive
721
- && self . is_non_raw_ident_where ( |id| {
748
+ && self . is_keywordable_ident_where ( |id| {
722
749
id. name . as_str ( ) . to_lowercase ( ) == kw. as_str ( ) . to_lowercase ( )
723
750
} ) )
724
751
}
725
752
726
753
pub fn is_path_segment_keyword ( & self ) -> bool {
727
- self . is_non_raw_ident_where ( Ident :: is_path_segment_keyword)
754
+ self . is_keywordable_ident_where ( Ident :: is_path_segment_keyword)
728
755
}
729
756
730
757
/// Returns true for reserved identifiers used internally for elided lifetimes,
731
758
/// unnamed method parameters, crate root module, error recovery etc.
732
759
pub fn is_special_ident ( & self ) -> bool {
733
- self . is_non_raw_ident_where ( Ident :: is_special)
760
+ self . is_keywordable_ident_where ( Ident :: is_special)
734
761
}
735
762
736
763
/// Returns `true` if the token is a keyword used in the language.
737
764
pub fn is_used_keyword ( & self ) -> bool {
738
- self . is_non_raw_ident_where ( Ident :: is_used_keyword)
765
+ self . is_keywordable_ident_where ( Ident :: is_used_keyword)
739
766
}
740
767
741
768
/// Returns `true` if the token is a keyword reserved for possible future use.
742
769
pub fn is_unused_keyword ( & self ) -> bool {
743
- self . is_non_raw_ident_where ( Ident :: is_unused_keyword)
770
+ self . is_keywordable_ident_where ( Ident :: is_unused_keyword)
744
771
}
745
772
746
773
/// Returns `true` if the token is either a special identifier or a keyword.
747
774
pub fn is_reserved_ident ( & self ) -> bool {
748
- self . is_non_raw_ident_where ( Ident :: is_reserved)
775
+ self . is_keywordable_ident_where ( Ident :: is_reserved)
749
776
}
750
777
751
778
/// Returns `true` if the token is the identifier `true` or `false`.
752
779
pub fn is_bool_lit ( & self ) -> bool {
753
- self . is_non_raw_ident_where ( |id| id. name . is_bool_lit ( ) )
780
+ self . is_keywordable_ident_where ( |id| id. name . is_bool_lit ( ) )
754
781
}
755
782
756
783
pub fn is_numeric_lit ( & self ) -> bool {
@@ -766,9 +793,9 @@ impl Token {
766
793
}
767
794
768
795
/// Returns `true` if the token is a non-raw identifier for which `pred` holds.
769
- pub fn is_non_raw_ident_where ( & self , pred : impl FnOnce ( Ident ) -> bool ) -> bool {
796
+ pub fn is_keywordable_ident_where ( & self , pred : impl FnOnce ( Ident ) -> bool ) -> bool {
770
797
match self . ident ( ) {
771
- Some ( ( id, false ) ) => pred ( id) ,
798
+ Some ( ( id, IdentKind :: Default | IdentKind :: Keyword ) ) => pred ( id) ,
772
799
_ => false ,
773
800
}
774
801
}
@@ -819,13 +846,13 @@ impl Token {
819
846
_ => return None ,
820
847
} ,
821
848
SingleQuote => match joint. kind {
822
- Ident ( name, false ) => Lifetime ( Symbol :: intern ( & format ! ( "'{name}" ) ) ) ,
849
+ Ident ( name, IdentKind :: Default ) => Lifetime ( Symbol :: intern ( & format ! ( "'{name}" ) ) ) ,
823
850
_ => return None ,
824
851
} ,
825
852
826
853
Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq ( ..) | At | DotDotDot
827
854
| DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar
828
- | Question | OpenDelim ( ..) | CloseDelim ( ..) | Literal ( ..) | Ident ( ..) | Keyword ( .. )
855
+ | Question | OpenDelim ( ..) | CloseDelim ( ..) | Literal ( ..) | Ident ( ..)
829
856
| Lifetime ( ..) | Interpolated ( ..) | DocComment ( ..) | Eof => return None ,
830
857
} ;
831
858
@@ -849,7 +876,7 @@ pub enum Nonterminal {
849
876
NtPat ( P < ast:: Pat > ) ,
850
877
NtExpr ( P < ast:: Expr > ) ,
851
878
NtTy ( P < ast:: Ty > ) ,
852
- NtIdent ( Ident , /* is_raw */ bool ) ,
879
+ NtIdent ( Ident , IdentKind ) ,
853
880
NtLifetime ( Ident ) ,
854
881
NtLiteral ( P < ast:: Expr > ) ,
855
882
/// Stuff inside brackets for attributes
0 commit comments