@@ -2533,10 +2533,16 @@ impl fmt::Debug for Ident {
25332533/// except that AST identifiers don't keep the rawness flag, so we have to guess it. 
25342534impl  fmt:: Display  for  Ident  { 
25352535    fn  fmt ( & self ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
2536-         fmt:: Display :: fmt ( & IdentPrinter :: new ( self . name ,  self . is_raw_guess ( ) ,  None ) ,  f) 
2536+         fmt:: Display :: fmt ( & IdentPrinter :: new ( self . name ,  self . guess_print_mode ( ) ,  None ) ,  f) 
25372537    } 
25382538} 
25392539
2540+ pub  enum  IdentPrintMode  { 
2541+     Normal , 
2542+     RawIdent , 
2543+     RawLifetime , 
2544+ } 
2545+ 
25402546/// The most general type to print identifiers. 
25412547/// 
25422548/// AST pretty-printer is used as a fallback for turning AST structures into token streams for 
@@ -2552,40 +2558,59 @@ impl fmt::Display for Ident {
25522558/// done for a token stream or a single token. 
25532559pub  struct  IdentPrinter  { 
25542560    symbol :  Symbol , 
2555-     is_raw :   bool , 
2561+     mode :   IdentPrintMode , 
25562562    /// Span used for retrieving the crate name to which `$crate` refers to, 
25572563     /// if this field is `None` then the `$crate` conversion doesn't happen. 
25582564     convert_dollar_crate :  Option < Span > , 
25592565} 
25602566
25612567impl  IdentPrinter  { 
25622568    /// The most general `IdentPrinter` constructor. Do not use this. 
2563-      pub  fn  new ( symbol :  Symbol ,  is_raw :  bool ,  convert_dollar_crate :  Option < Span > )  -> IdentPrinter  { 
2564-         IdentPrinter  {  symbol,  is_raw,  convert_dollar_crate } 
2569+      pub  fn  new ( 
2570+         symbol :  Symbol , 
2571+         mode :  IdentPrintMode , 
2572+         convert_dollar_crate :  Option < Span > , 
2573+     )  -> IdentPrinter  { 
2574+         IdentPrinter  {  symbol,  mode,  convert_dollar_crate } 
25652575    } 
25662576
25672577    /// This implementation is supposed to be used when printing identifiers 
25682578     /// as a part of pretty-printing for larger AST pieces. 
25692579     /// Do not use this either. 
2570-      pub  fn  for_ast_ident ( ident :  Ident ,  is_raw :   bool )  -> IdentPrinter  { 
2571-         IdentPrinter :: new ( ident. name ,  is_raw ,  Some ( ident. span ) ) 
2580+      pub  fn  for_ast_ident ( ident :  Ident ,  mode :   IdentPrintMode )  -> IdentPrinter  { 
2581+         IdentPrinter :: new ( ident. name ,  mode ,  Some ( ident. span ) ) 
25722582    } 
25732583} 
25742584
25752585impl  fmt:: Display  for  IdentPrinter  { 
25762586    fn  fmt ( & self ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
2577-         if  self . is_raw  { 
2578-             f. write_str ( "r#" ) ?; 
2579-         }  else  if  self . symbol  == kw:: DollarCrate  { 
2580-             if  let  Some ( span)  = self . convert_dollar_crate  { 
2587+         let  s = match  self . mode  { 
2588+             IdentPrintMode :: Normal 
2589+                 if  self . symbol  == kw:: DollarCrate 
2590+                     && let  Some ( span)  = self . convert_dollar_crate  =>
2591+             { 
25812592                let  converted = span. ctxt ( ) . dollar_crate_name ( ) ; 
25822593                if  !converted. is_path_segment_keyword ( )  { 
25832594                    f. write_str ( "::" ) ?; 
25842595                } 
2585-                 return  fmt :: Display :: fmt ( & converted,  f ) ; 
2596+                 converted
25862597            } 
2587-         } 
2588-         fmt:: Display :: fmt ( & self . symbol ,  f) 
2598+             IdentPrintMode :: Normal  => self . symbol , 
2599+             IdentPrintMode :: RawIdent  => { 
2600+                 f. write_str ( "r#" ) ?; 
2601+                 self . symbol 
2602+             } 
2603+             IdentPrintMode :: RawLifetime  => { 
2604+                 f. write_str ( "'r#" ) ?; 
2605+                 let  s = self 
2606+                     . symbol 
2607+                     . as_str ( ) 
2608+                     . strip_prefix ( "'" ) 
2609+                     . expect ( "only lifetime idents should be passed with RawLifetime mode" ) ; 
2610+                 Symbol :: intern ( s) 
2611+             } 
2612+         } ; 
2613+         s. fmt ( f) 
25892614    } 
25902615} 
25912616
@@ -3020,6 +3045,29 @@ impl Ident {
30203045        self . name . can_be_raw ( )  && self . is_reserved ( ) 
30213046    } 
30223047
3048+     /// Given the name of a lifetime without the first quote (`'`), 
3049+      /// returns whether the lifetime name is reserved (therefore invalid) 
3050+      pub  fn  is_reserved_lifetime ( self )  -> bool  { 
3051+         self . is_reserved ( )  && ![ kw:: Underscore ,  kw:: Static ] . contains ( & self . name ) 
3052+     } 
3053+ 
3054+     pub  fn  is_raw_lifetime_guess ( self )  -> bool  { 
3055+         let  name_without_apostrophe = self . without_first_quote ( ) ; 
3056+         name_without_apostrophe. name  != self . name 
3057+             && name_without_apostrophe. name . can_be_raw ( ) 
3058+             && name_without_apostrophe. is_reserved_lifetime ( ) 
3059+     } 
3060+ 
3061+     pub  fn  guess_print_mode ( self )  -> IdentPrintMode  { 
3062+         if  self . is_raw_lifetime_guess ( )  { 
3063+             IdentPrintMode :: RawLifetime 
3064+         }  else  if  self . is_raw_guess ( )  { 
3065+             IdentPrintMode :: RawIdent 
3066+         }  else  { 
3067+             IdentPrintMode :: Normal 
3068+         } 
3069+     } 
3070+ 
30233071    /// Whether this would be the identifier for a tuple field like `self.0`, as 
30243072     /// opposed to a named field like `self.thing`. 
30253073     pub  fn  is_numeric ( self )  -> bool  { 
0 commit comments