@@ -2533,10 +2533,16 @@ impl fmt::Debug for Ident {
2533
2533
/// except that AST identifiers don't keep the rawness flag, so we have to guess it.
2534
2534
impl fmt:: Display for Ident {
2535
2535
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)
2537
2537
}
2538
2538
}
2539
2539
2540
+ pub enum IdentPrintMode {
2541
+ Normal ,
2542
+ RawIdent ,
2543
+ RawLifetime ,
2544
+ }
2545
+
2540
2546
/// The most general type to print identifiers.
2541
2547
///
2542
2548
/// 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 {
2552
2558
/// done for a token stream or a single token.
2553
2559
pub struct IdentPrinter {
2554
2560
symbol : Symbol ,
2555
- is_raw : bool ,
2561
+ mode : IdentPrintMode ,
2556
2562
/// Span used for retrieving the crate name to which `$crate` refers to,
2557
2563
/// if this field is `None` then the `$crate` conversion doesn't happen.
2558
2564
convert_dollar_crate : Option < Span > ,
2559
2565
}
2560
2566
2561
2567
impl IdentPrinter {
2562
2568
/// 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 }
2565
2575
}
2566
2576
2567
2577
/// This implementation is supposed to be used when printing identifiers
2568
2578
/// as a part of pretty-printing for larger AST pieces.
2569
2579
/// 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 ) )
2572
2582
}
2573
2583
}
2574
2584
2575
2585
impl fmt:: Display for IdentPrinter {
2576
2586
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
+ {
2581
2592
let converted = span. ctxt ( ) . dollar_crate_name ( ) ;
2582
2593
if !converted. is_path_segment_keyword ( ) {
2583
2594
f. write_str ( "::" ) ?;
2584
2595
}
2585
- return fmt :: Display :: fmt ( & converted, f ) ;
2596
+ converted
2586
2597
}
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)
2589
2614
}
2590
2615
}
2591
2616
@@ -3020,6 +3045,29 @@ impl Ident {
3020
3045
self . name . can_be_raw ( ) && self . is_reserved ( )
3021
3046
}
3022
3047
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
+
3023
3071
/// Whether this would be the identifier for a tuple field like `self.0`, as
3024
3072
/// opposed to a named field like `self.thing`.
3025
3073
pub fn is_numeric ( self ) -> bool {
0 commit comments