@@ -107,7 +107,9 @@ impl Lit {
107107 /// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation.
108108 pub fn from_token ( token : & Token ) -> Option < Lit > {
109109 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+ }
111113 Literal ( token_lit) => Some ( token_lit) ,
112114 Interpolated ( ref nt)
113115 if let NtExpr ( expr) | NtLiteral ( expr) = & nt. 0
@@ -183,8 +185,8 @@ impl LitKind {
183185 }
184186}
185187
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) ;
188190
189191 !ident_token. is_reserved_ident ( )
190192 || ident_token. is_path_segment_keyword ( )
@@ -212,15 +214,37 @@ pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool {
212214 kw:: Static ,
213215 ]
214216 . contains ( & name)
217+ || kind == IdentKind :: Keyword
215218}
216219
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) ;
219222
220223 !ident_token. is_reserved_ident ( )
221224 || ident_token. is_path_segment_keyword ( )
222225 || [ kw:: Underscore , kw:: For , kw:: Impl , kw:: Fn , kw:: Unsafe , kw:: Extern , kw:: Typeof , kw:: Dyn ]
223226 . 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+ }
224248}
225249
226250// SAFETY: due to the `Clone` impl below, all fields of all variants other than
@@ -298,10 +322,7 @@ pub enum TokenKind {
298322 /// Do not forget about `NtIdent` when you want to match on identifiers.
299323 /// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to
300324 /// 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 ) ,
305326
306327 /// Lifetime identifier token.
307328 /// Do not forget about `NtLifetime` when you want to match on lifetime identifiers.
@@ -415,7 +436,13 @@ impl Token {
415436
416437 /// Recovers a `Token` from an `Ident`. This creates a raw identifier if necessary.
417438 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+ )
419446 }
420447
421448 /// For interpolated tokens, returns a span of the fragment to which the interpolated
@@ -442,7 +469,7 @@ impl Token {
442469 | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote => true ,
443470
444471 OpenDelim ( ..) | CloseDelim ( ..) | Literal ( ..) | DocComment ( ..) | Ident ( ..)
445- | Keyword ( .. ) | Lifetime ( ..) | Interpolated ( ..) | Eof => false ,
472+ | Lifetime ( ..) | Interpolated ( ..) | Eof => false ,
446473 }
447474 }
448475
@@ -571,7 +598,7 @@ impl Token {
571598 pub fn can_begin_literal_maybe_minus ( & self ) -> bool {
572599 match self . uninterpolate ( ) . kind {
573600 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 ,
575602 Interpolated ( ref nt) => match & nt. 0 {
576603 NtLiteral ( _) => true ,
577604 NtExpr ( e) => match & e. kind {
@@ -606,10 +633,10 @@ impl Token {
606633
607634 /// Returns an identifier if this token is an identifier.
608635 #[ inline]
609- pub fn ident ( & self ) -> Option < ( Ident , /* is_raw */ bool ) > {
636+ pub fn ident ( & self ) -> Option < ( Ident , IdentKind ) > {
610637 // We avoid using `Token::uninterpolate` here because it's slow.
611638 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 ) ) ,
613640 Interpolated ( nt) => match & nt. 0 {
614641 NtIdent ( ident, is_raw) => Some ( ( * ident, * is_raw) ) ,
615642 _ => None ,
@@ -702,46 +729,46 @@ impl Token {
702729
703730 /// Returns `true` if the token is a given keyword, `kw`.
704731 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)
706733 }
707734
708735 /// 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.
709736 pub fn is_keyword_case ( & self , kw : Symbol , case : Case ) -> bool {
710737 self . is_keyword ( kw)
711738 || ( case == Case :: Insensitive
712- && self . is_non_raw_ident_where ( |id| {
739+ && self . is_keywordable_ident_where ( |id| {
713740 id. name . as_str ( ) . to_lowercase ( ) == kw. as_str ( ) . to_lowercase ( )
714741 } ) )
715742 }
716743
717744 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)
719746 }
720747
721748 /// Returns true for reserved identifiers used internally for elided lifetimes,
722749 /// unnamed method parameters, crate root module, error recovery etc.
723750 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)
725752 }
726753
727754 /// Returns `true` if the token is a keyword used in the language.
728755 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)
730757 }
731758
732759 /// Returns `true` if the token is a keyword reserved for possible future use.
733760 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)
735762 }
736763
737764 /// Returns `true` if the token is either a special identifier or a keyword.
738765 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)
740767 }
741768
742769 /// Returns `true` if the token is the identifier `true` or `false`.
743770 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 ( ) )
745772 }
746773
747774 pub fn is_numeric_lit ( & self ) -> bool {
@@ -757,9 +784,9 @@ impl Token {
757784 }
758785
759786 /// 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 {
761788 match self . ident ( ) {
762- Some ( ( id, false ) ) => pred ( id) ,
789+ Some ( ( id, IdentKind :: Default | IdentKind :: Keyword ) ) => pred ( id) ,
763790 _ => false ,
764791 }
765792 }
@@ -810,13 +837,13 @@ impl Token {
810837 _ => return None ,
811838 } ,
812839 SingleQuote => match joint. kind {
813- Ident ( name, false ) => Lifetime ( Symbol :: intern ( & format ! ( "'{name}" ) ) ) ,
840+ Ident ( name, IdentKind :: Default ) => Lifetime ( Symbol :: intern ( & format ! ( "'{name}" ) ) ) ,
814841 _ => return None ,
815842 } ,
816843
817844 Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq ( ..) | At | DotDotDot
818845 | DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar
819- | Question | OpenDelim ( ..) | CloseDelim ( ..) | Literal ( ..) | Ident ( ..) | Keyword ( .. )
846+ | Question | OpenDelim ( ..) | CloseDelim ( ..) | Literal ( ..) | Ident ( ..)
820847 | Lifetime ( ..) | Interpolated ( ..) | DocComment ( ..) | Eof => return None ,
821848 } ;
822849
@@ -840,7 +867,7 @@ pub enum Nonterminal {
840867 NtPat ( P < ast:: Pat > ) ,
841868 NtExpr ( P < ast:: Expr > ) ,
842869 NtTy ( P < ast:: Ty > ) ,
843- NtIdent ( Ident , /* is_raw */ bool ) ,
870+ NtIdent ( Ident , IdentKind ) ,
844871 NtLifetime ( Ident ) ,
845872 NtLiteral ( P < ast:: Expr > ) ,
846873 /// Stuff inside brackets for attributes
0 commit comments