11//! Code related to parsing literals. 
22
3- use  crate :: ast:: { self ,  LitKind ,  MetaItemLit } ; 
3+ use  crate :: ast:: { self ,  LitKind ,  MetaItemLit ,   StrStyle } ; 
44use  crate :: token:: { self ,  Token } ; 
55use  rustc_lexer:: unescape:: { byte_from_char,  unescape_byte,  unescape_char,  unescape_literal,  Mode } ; 
66use  rustc_span:: symbol:: { kw,  sym,  Symbol } ; 
77use  rustc_span:: Span ; 
8- use  std:: ascii; 
8+ use  std:: { ascii,  fmt,  str} ; 
9+ 
10+ // Escapes a string, represented as a symbol. Reuses the original symbol, 
11+ // avoiding interning, if no changes are required. 
12+ pub  fn  escape_string_symbol ( symbol :  Symbol )  -> Symbol  { 
13+     let  s = symbol. as_str ( ) ; 
14+     let  escaped = s. escape_default ( ) . to_string ( ) ; 
15+     if  s == escaped {  symbol }  else  {  Symbol :: intern ( & escaped)  } 
16+ } 
17+ 
18+ // Escapes a char. 
19+ pub  fn  escape_char_symbol ( ch :  char )  -> Symbol  { 
20+     let  s:  String  = ch. escape_default ( ) . map ( Into :: < char > :: into) . collect ( ) ; 
21+     Symbol :: intern ( & s) 
22+ } 
23+ 
24+ // Escapes a byte string. 
25+ pub  fn  escape_byte_str_symbol ( bytes :  & [ u8 ] )  -> Symbol  { 
26+     let  s = bytes. escape_ascii ( ) . to_string ( ) ; 
27+     Symbol :: intern ( & s) 
28+ } 
929
1030#[ derive( Debug ) ]  
1131pub  enum  LitError  { 
@@ -115,9 +135,9 @@ impl LitKind {
115135                    } 
116136                } ) ; 
117137                error?; 
118-                 LitKind :: ByteStr ( buf. into ( ) ) 
138+                 LitKind :: ByteStr ( buf. into ( ) ,   StrStyle :: Cooked ) 
119139            } 
120-             token:: ByteStrRaw ( _ )  => { 
140+             token:: ByteStrRaw ( n )  => { 
121141                let  s = symbol. as_str ( ) ; 
122142                let  bytes = if  s. contains ( '\r' )  { 
123143                    let  mut  buf = Vec :: with_capacity ( s. len ( ) ) ; 
@@ -136,69 +156,95 @@ impl LitKind {
136156                    symbol. to_string ( ) . into_bytes ( ) 
137157                } ; 
138158
139-                 LitKind :: ByteStr ( bytes. into ( ) ) 
159+                 LitKind :: ByteStr ( bytes. into ( ) ,   StrStyle :: Raw ( n ) ) 
140160            } 
141161            token:: Err  => LitKind :: Err , 
142162        } ) 
143163    } 
164+ } 
144165
145-     /// Attempts to recover a token from semantic literal. 
146-      /// This function is used when the original token doesn't exist (e.g. the literal is created 
147-      /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). 
148-      pub  fn  to_token_lit ( & self )  -> token:: Lit  { 
149-         let  ( kind,  symbol,  suffix)  = match  * self  { 
150-             LitKind :: Str ( symbol,  ast:: StrStyle :: Cooked )  => { 
151-                 // Don't re-intern unless the escaped string is different. 
152-                 let  s = symbol. as_str ( ) ; 
153-                 let  escaped = s. escape_default ( ) . to_string ( ) ; 
154-                 let  symbol = if  s == escaped {  symbol }  else  {  Symbol :: intern ( & escaped)  } ; 
155-                 ( token:: Str ,  symbol,  None ) 
156-             } 
157-             LitKind :: Str ( symbol,  ast:: StrStyle :: Raw ( n) )  => ( token:: StrRaw ( n) ,  symbol,  None ) , 
158-             LitKind :: ByteStr ( ref  bytes)  => { 
159-                 let  string = bytes. escape_ascii ( ) . to_string ( ) ; 
160-                 ( token:: ByteStr ,  Symbol :: intern ( & string) ,  None ) 
166+ impl  fmt:: Display  for  LitKind  { 
167+     fn  fmt ( & self ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
168+         match  * self  { 
169+             LitKind :: Byte ( b)  => { 
170+                 let  b:  String  = ascii:: escape_default ( b) . map ( Into :: < char > :: into) . collect ( ) ; 
171+                 write ! ( f,  "b'{}'" ,  b) ?; 
161172            } 
162-             LitKind :: Byte ( byte)  => { 
163-                 let  string:  String  = ascii:: escape_default ( byte) . map ( Into :: < char > :: into) . collect ( ) ; 
164-                 ( token:: Byte ,  Symbol :: intern ( & string) ,  None ) 
173+             LitKind :: Char ( ch)  => write ! ( f,  "'{}'" ,  escape_char_symbol( ch) ) ?, 
174+             LitKind :: Str ( sym,  StrStyle :: Cooked )  => write ! ( f,  "\" {}\" " ,  escape_string_symbol( sym) ) ?, 
175+             LitKind :: Str ( sym,  StrStyle :: Raw ( n) )  => write ! ( 
176+                 f, 
177+                 "r{delim}\" {string}\" {delim}" , 
178+                 delim = "#" . repeat( n as  usize ) , 
179+                 string = sym
180+             ) ?, 
181+             LitKind :: ByteStr ( ref  bytes,  StrStyle :: Cooked )  => { 
182+                 write ! ( f,  "b\" {}\" " ,  escape_byte_str_symbol( bytes) ) ?
165183            } 
166-             LitKind :: Char ( ch)  => { 
167-                 let  string:  String  = ch. escape_default ( ) . map ( Into :: < char > :: into) . collect ( ) ; 
168-                 ( token:: Char ,  Symbol :: intern ( & string) ,  None ) 
184+             LitKind :: ByteStr ( ref  bytes,  StrStyle :: Raw ( n) )  => { 
185+                 // Unwrap because raw byte string literals can only contain ASCII. 
186+                 let  symbol = str:: from_utf8 ( bytes) . unwrap ( ) ; 
187+                 write ! ( 
188+                     f, 
189+                     "br{delim}\" {string}\" {delim}" , 
190+                     delim = "#" . repeat( n as  usize ) , 
191+                     string = symbol
192+                 ) ?; 
169193            } 
170194            LitKind :: Int ( n,  ty)  => { 
171-                 let  suffix =  match  ty  { 
172-                     ast :: LitIntType :: Unsigned ( ty )  =>  Some ( ty . name ( ) ) , 
173-                     ast:: LitIntType :: Signed ( ty)  => Some ( ty. name ( ) ) , 
174-                     ast:: LitIntType :: Unsuffixed  => None , 
175-                 } ; 
176-                 ( token :: Integer ,  sym :: integer ( n ) ,  suffix ) 
195+                 write ! ( f ,   "{}" ,  n ) ? ; 
196+                 match  ty  { 
197+                     ast:: LitIntType :: Unsigned ( ty)  => write ! ( f ,   "{}" ,   ty. name( ) ) ? , 
198+                     ast:: LitIntType :: Signed ( ty )  => write ! ( f ,   "{}" ,  ty . name ( ) ) ? , 
199+                     ast :: LitIntType :: Unsuffixed  =>  { } 
200+                 } 
177201            } 
178202            LitKind :: Float ( symbol,  ty)  => { 
179-                 let  suffix =  match  ty  { 
180-                     ast :: LitFloatType :: Suffixed ( ty )  =>  Some ( ty . name ( ) ) , 
181-                     ast:: LitFloatType :: Unsuffixed  => None , 
182-                 } ; 
183-                 ( token :: Float ,  symbol ,  suffix ) 
203+                 write ! ( f ,   "{}" ,  symbol ) ? ; 
204+                 match  ty  { 
205+                     ast:: LitFloatType :: Suffixed ( ty )  => write ! ( f ,   "{}" ,  ty . name ( ) ) ? , 
206+                     ast :: LitFloatType :: Unsuffixed  =>  { } 
207+                 } 
184208            } 
185-             LitKind :: Bool ( value)  => { 
186-                 let  symbol = if  value {  kw:: True  }  else  {  kw:: False  } ; 
187-                 ( token:: Bool ,  symbol,  None ) 
209+             LitKind :: Bool ( b)  => write ! ( f,  "{}" ,  if  b {  "true"  }  else {  "false"  } ) ?, 
210+             LitKind :: Err  => { 
211+                 // This only shows up in places like `-Zunpretty=hir` output, so we 
212+                 // don't bother to produce something useful. 
213+                 write ! ( f,  "<bad-literal>" ) ?; 
188214            } 
189-             // This only shows up in places like `-Zunpretty=hir` output, so we 
190-             // don't bother to produce something useful. 
191-             LitKind :: Err  => ( token:: Err ,  Symbol :: intern ( "<bad-literal>" ) ,  None ) , 
192-         } ; 
215+         } 
193216
194-         token :: Lit :: new ( kind ,  symbol ,  suffix ) 
217+         Ok ( ( ) ) 
195218    } 
196219} 
197220
198221impl  MetaItemLit  { 
199-     /// Converts token literal into a meta item literal. 
222+     /// Converts a  token literal into a meta item literal. 
200223     pub  fn  from_token_lit ( token_lit :  token:: Lit ,  span :  Span )  -> Result < MetaItemLit ,  LitError >  { 
201-         Ok ( MetaItemLit  {  token_lit,  kind :  LitKind :: from_token_lit ( token_lit) ?,  span } ) 
224+         Ok ( MetaItemLit  { 
225+             symbol :  token_lit. symbol , 
226+             suffix :  token_lit. suffix , 
227+             kind :  LitKind :: from_token_lit ( token_lit) ?, 
228+             span, 
229+         } ) 
230+     } 
231+ 
232+     /// Cheaply converts a meta item literal into a token literal. 
233+      pub  fn  as_token_lit ( & self )  -> token:: Lit  { 
234+         let  kind = match  self . kind  { 
235+             LitKind :: Bool ( _)  => token:: Bool , 
236+             LitKind :: Str ( _,  ast:: StrStyle :: Cooked )  => token:: Str , 
237+             LitKind :: Str ( _,  ast:: StrStyle :: Raw ( n) )  => token:: StrRaw ( n) , 
238+             LitKind :: ByteStr ( _,  ast:: StrStyle :: Cooked )  => token:: ByteStr , 
239+             LitKind :: ByteStr ( _,  ast:: StrStyle :: Raw ( n) )  => token:: ByteStrRaw ( n) , 
240+             LitKind :: Byte ( _)  => token:: Byte , 
241+             LitKind :: Char ( _)  => token:: Char , 
242+             LitKind :: Int ( ..)  => token:: Integer , 
243+             LitKind :: Float ( ..)  => token:: Float , 
244+             LitKind :: Err  => token:: Err , 
245+         } ; 
246+ 
247+         token:: Lit :: new ( kind,  self . symbol ,  self . suffix ) 
202248    } 
203249
204250    /// Converts an arbitrary token into meta item literal. 
0 commit comments