@@ -812,6 +812,7 @@ symbols! {
812812 default_field_values,
813813 default_fn,
814814 default_lib_allocator,
815+ default_lifetime: "'a" ,
815816 default_method_body_is_const,
816817 // --------------------------
817818 // Lang items which are used only for experiments with auto traits with default bounds.
@@ -2477,6 +2478,10 @@ impl Ident {
24772478 pub fn as_str ( & self ) -> & str {
24782479 self . name . as_str ( )
24792480 }
2481+
2482+ pub fn as_lifetime ( & self ) -> Option < Ident > {
2483+ self . name . as_lifetime ( ) . map ( |sym| Ident :: with_dummy_span ( sym) )
2484+ }
24802485}
24812486
24822487impl PartialEq for Ident {
@@ -2546,6 +2551,14 @@ impl IdentPrinter {
25462551
25472552impl fmt:: Display for IdentPrinter {
25482553 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2554+ if let Some ( lifetime) = self . symbol . as_lifetime ( ) {
2555+ f. write_str ( "'" ) ?;
2556+ if self . is_raw {
2557+ f. write_str ( "r#" ) ?;
2558+ }
2559+ return fmt:: Display :: fmt ( & lifetime, f) ;
2560+ }
2561+
25492562 if self . is_raw {
25502563 f. write_str ( "r#" ) ?;
25512564 } else if self . symbol == kw:: DollarCrate {
@@ -2640,6 +2653,11 @@ impl Symbol {
26402653 self == sym:: empty
26412654 }
26422655
2656+ pub fn as_lifetime ( self ) -> Option < Symbol > {
2657+ let name = self . as_str ( ) ;
2658+ name. strip_prefix ( "'" ) . map ( Symbol :: intern)
2659+ }
2660+
26432661 /// This method is supposed to be used in error messages, so it's expected to be
26442662 /// identical to printing the original identifier token written in source code
26452663 /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
@@ -2946,7 +2964,13 @@ impl Ident {
29462964 /// We see this identifier in a normal identifier position, like variable name or a type.
29472965 /// How was it written originally? Did it use the raw form? Let's try to guess.
29482966 pub fn is_raw_guess ( self ) -> bool {
2949- self . name . can_be_raw ( ) && self . is_reserved ( )
2967+ if self . name == kw:: StaticLifetime || self . name == kw:: UnderscoreLifetime {
2968+ false
2969+ } else if let Some ( lifetime) = self . as_lifetime ( ) {
2970+ lifetime. is_raw_guess ( )
2971+ } else {
2972+ self . name . can_be_raw ( ) && self . is_reserved ( )
2973+ }
29502974 }
29512975
29522976 /// Whether this would be the identifier for a tuple field like `self.0`, as
@@ -2972,3 +2996,27 @@ pub fn used_keywords(edition: impl Copy + FnOnce() -> Edition) -> Vec<Symbol> {
29722996 } )
29732997 . collect ( )
29742998}
2999+
3000+ /// A newtype around `Symbol` specifically for label printing.
3001+ /// This ensures type safety when dealing with labels and provides
3002+ /// specialized formatting behavior for label contexts.
3003+ #[ derive( Copy , Clone , Eq , PartialEq , Hash , Debug ) ]
3004+ pub struct LabelSymbol ( Symbol ) ;
3005+
3006+ impl fmt:: Display for LabelSymbol {
3007+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
3008+ write ! ( f, "{}" , self . 0 . as_str( ) )
3009+ }
3010+ }
3011+
3012+ impl From < Symbol > for LabelSymbol {
3013+ fn from ( symbol : Symbol ) -> Self {
3014+ LabelSymbol ( symbol)
3015+ }
3016+ }
3017+
3018+ impl From < Ident > for LabelSymbol {
3019+ fn from ( ident : Ident ) -> Self {
3020+ LabelSymbol ( ident. name )
3021+ }
3022+ }
0 commit comments