11//! Code related to parsing literals.
22
33use crate :: ast:: { self , Lit , LitKind } ;
4- use crate :: parse:: parser:: Parser ;
5- use crate :: parse:: PResult ;
6- use crate :: parse:: token:: { self , Token , TokenKind } ;
7- use crate :: print:: pprust;
4+ use crate :: parse:: token:: { self , Token } ;
85use crate :: symbol:: { kw, sym, Symbol } ;
96use crate :: tokenstream:: { TokenStream , TokenTree } ;
107
11- use errors:: { Applicability , Handler } ;
128use log:: debug;
139use rustc_data_structures:: sync:: Lrc ;
1410use syntax_pos:: Span ;
@@ -28,72 +24,6 @@ crate enum LitError {
2824 IntTooLarge ,
2925}
3026
31- impl LitError {
32- fn report ( & self , diag : & Handler , lit : token:: Lit , span : Span ) {
33- let token:: Lit { kind, suffix, .. } = lit;
34- match * self {
35- // `NotLiteral` is not an error by itself, so we don't report
36- // it and give the parser opportunity to try something else.
37- LitError :: NotLiteral => { }
38- // `LexerError` *is* an error, but it was already reported
39- // by lexer, so here we don't report it the second time.
40- LitError :: LexerError => { }
41- LitError :: InvalidSuffix => {
42- expect_no_suffix (
43- diag, span, & format ! ( "{} {} literal" , kind. article( ) , kind. descr( ) ) , suffix
44- ) ;
45- }
46- LitError :: InvalidIntSuffix => {
47- let suf = suffix. expect ( "suffix error with no suffix" ) . as_str ( ) ;
48- if looks_like_width_suffix ( & [ 'i' , 'u' ] , & suf) {
49- // If it looks like a width, try to be helpful.
50- let msg = format ! ( "invalid width `{}` for integer literal" , & suf[ 1 ..] ) ;
51- diag. struct_span_err ( span, & msg)
52- . help ( "valid widths are 8, 16, 32, 64 and 128" )
53- . emit ( ) ;
54- } else {
55- let msg = format ! ( "invalid suffix `{}` for integer literal" , suf) ;
56- diag. struct_span_err ( span, & msg)
57- . span_label ( span, format ! ( "invalid suffix `{}`" , suf) )
58- . help ( "the suffix must be one of the integral types (`u32`, `isize`, etc)" )
59- . emit ( ) ;
60- }
61- }
62- LitError :: InvalidFloatSuffix => {
63- let suf = suffix. expect ( "suffix error with no suffix" ) . as_str ( ) ;
64- if looks_like_width_suffix ( & [ 'f' ] , & suf) {
65- // If it looks like a width, try to be helpful.
66- let msg = format ! ( "invalid width `{}` for float literal" , & suf[ 1 ..] ) ;
67- diag. struct_span_err ( span, & msg)
68- . help ( "valid widths are 32 and 64" )
69- . emit ( ) ;
70- } else {
71- let msg = format ! ( "invalid suffix `{}` for float literal" , suf) ;
72- diag. struct_span_err ( span, & msg)
73- . span_label ( span, format ! ( "invalid suffix `{}`" , suf) )
74- . help ( "valid suffixes are `f32` and `f64`" )
75- . emit ( ) ;
76- }
77- }
78- LitError :: NonDecimalFloat ( base) => {
79- let descr = match base {
80- 16 => "hexadecimal" ,
81- 8 => "octal" ,
82- 2 => "binary" ,
83- _ => unreachable ! ( ) ,
84- } ;
85- diag. struct_span_err ( span, & format ! ( "{} float literal is not supported" , descr) )
86- . span_label ( span, "not supported" )
87- . emit ( ) ;
88- }
89- LitError :: IntTooLarge => {
90- diag. struct_span_err ( span, "integer literal is too large" )
91- . emit ( ) ;
92- }
93- }
94- }
95- }
96-
9727impl LitKind {
9828 /// Converts literal token into a semantic literal.
9929 fn from_lit_token ( lit : token:: Lit ) -> Result < LitKind , LitError > {
@@ -254,7 +184,7 @@ impl LitKind {
254184
255185impl Lit {
256186 /// Converts literal token into an AST literal.
257- fn from_lit_token ( token : token:: Lit , span : Span ) -> Result < Lit , LitError > {
187+ crate fn from_lit_token ( token : token:: Lit , span : Span ) -> Result < Lit , LitError > {
258188 Ok ( Lit { token, kind : LitKind :: from_lit_token ( token) ?, span } )
259189 }
260190
@@ -296,99 +226,6 @@ impl Lit {
296226 }
297227}
298228
299- impl < ' a > Parser < ' a > {
300- /// Matches `lit = true | false | token_lit`.
301- crate fn parse_lit ( & mut self ) -> PResult < ' a , Lit > {
302- let mut recovered = None ;
303- if self . token == token:: Dot {
304- // Attempt to recover `.4` as `0.4`.
305- recovered = self . look_ahead ( 1 , |next_token| {
306- if let token:: Literal ( token:: Lit { kind : token:: Integer , symbol, suffix } )
307- = next_token. kind {
308- if self . token . span . hi ( ) == next_token. span . lo ( ) {
309- let s = String :: from ( "0." ) + & symbol. as_str ( ) ;
310- let kind = TokenKind :: lit ( token:: Float , Symbol :: intern ( & s) , suffix) ;
311- return Some ( Token :: new ( kind, self . token . span . to ( next_token. span ) ) ) ;
312- }
313- }
314- None
315- } ) ;
316- if let Some ( token) = & recovered {
317- self . bump ( ) ;
318- self . diagnostic ( )
319- . struct_span_err ( token. span , "float literals must have an integer part" )
320- . span_suggestion (
321- token. span ,
322- "must have an integer part" ,
323- pprust:: token_to_string ( token) ,
324- Applicability :: MachineApplicable ,
325- )
326- . emit ( ) ;
327- }
328- }
329-
330- let token = recovered. as_ref ( ) . unwrap_or ( & self . token ) ;
331- match Lit :: from_token ( token) {
332- Ok ( lit) => {
333- self . bump ( ) ;
334- Ok ( lit)
335- }
336- Err ( LitError :: NotLiteral ) => {
337- let msg = format ! ( "unexpected token: {}" , self . this_token_descr( ) ) ;
338- Err ( self . span_fatal ( token. span , & msg) )
339- }
340- Err ( err) => {
341- let ( lit, span) = ( token. expect_lit ( ) , token. span ) ;
342- self . bump ( ) ;
343- err. report ( & self . sess . span_diagnostic , lit, span) ;
344- // Pack possible quotes and prefixes from the original literal into
345- // the error literal's symbol so they can be pretty-printed faithfully.
346- let suffixless_lit = token:: Lit :: new ( lit. kind , lit. symbol , None ) ;
347- let symbol = Symbol :: intern ( & suffixless_lit. to_string ( ) ) ;
348- let lit = token:: Lit :: new ( token:: Err , symbol, lit. suffix ) ;
349- Lit :: from_lit_token ( lit, span) . map_err ( |_| unreachable ! ( ) )
350- }
351- }
352- }
353- }
354-
355- crate fn expect_no_suffix ( diag : & Handler , sp : Span , kind : & str , suffix : Option < Symbol > ) {
356- if let Some ( suf) = suffix {
357- let mut err = if kind == "a tuple index" &&
358- [ sym:: i32, sym:: u32, sym:: isize, sym:: usize] . contains ( & suf) {
359- // #59553: warn instead of reject out of hand to allow the fix to percolate
360- // through the ecosystem when people fix their macros
361- let mut err = diag. struct_span_warn (
362- sp,
363- & format ! ( "suffixes on {} are invalid" , kind) ,
364- ) ;
365- err. note ( & format ! (
366- "`{}` is *temporarily* accepted on tuple index fields as it was \
367- incorrectly accepted on stable for a few releases",
368- suf,
369- ) ) ;
370- err. help (
371- "on proc macros, you'll want to use `syn::Index::from` or \
372- `proc_macro::Literal::*_unsuffixed` for code that will desugar \
373- to tuple field access",
374- ) ;
375- err. note (
376- "for more context, see https://github.com/rust-lang/rust/issues/60210" ,
377- ) ;
378- err
379- } else {
380- diag. struct_span_err ( sp, & format ! ( "suffixes on {} are invalid" , kind) )
381- } ;
382- err. span_label ( sp, format ! ( "invalid suffix `{}`" , suf) ) ;
383- err. emit ( ) ;
384- }
385- }
386-
387- // Checks if `s` looks like i32 or u1234 etc.
388- fn looks_like_width_suffix ( first_chars : & [ char ] , s : & str ) -> bool {
389- s. len ( ) > 1 && s. starts_with ( first_chars) && s[ 1 ..] . chars ( ) . all ( |c| c. is_ascii_digit ( ) )
390- }
391-
392229fn strip_underscores ( symbol : Symbol ) -> Symbol {
393230 // Do not allocate a new string unless necessary.
394231 let s = symbol. as_str ( ) ;
0 commit comments