@@ -291,20 +291,33 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
291
291
s. len ( ) > 1 && s. starts_with ( first_chars) && s[ 1 ..] . chars ( ) . all ( |c| c. is_ascii_digit ( ) )
292
292
}
293
293
294
- // Try to lowercase the prefix if it's a valid base prefix.
295
- fn fix_base_capitalisation ( s : & str ) -> Option < String > {
296
- if let Some ( stripped) = s. strip_prefix ( 'B' ) {
297
- Some ( format ! ( "0b{stripped}" ) )
298
- } else if let Some ( stripped) = s. strip_prefix ( 'O' ) {
299
- Some ( format ! ( "0o{stripped}" ) )
300
- } else if let Some ( stripped) = s. strip_prefix ( 'X' ) {
301
- Some ( format ! ( "0x{stripped}" ) )
294
+ // Try to lowercase the prefix if the prefix and suffix are valid.
295
+ fn fix_base_capitalisation ( prefix : & str , suffix : & str ) -> Option < String > {
296
+ let mut chars = suffix. chars ( ) ;
297
+
298
+ let base_char = chars. next ( ) . unwrap ( ) ;
299
+ let base = match base_char {
300
+ 'B' => 2 ,
301
+ 'O' => 8 ,
302
+ 'X' => 16 ,
303
+ _ => return None ,
304
+ } ;
305
+
306
+ // check that the suffix contains only base-appropriate characters
307
+ let valid = prefix == "0"
308
+ && chars
309
+ . filter ( |c| * c != '_' )
310
+ . take_while ( |c| * c != 'i' && * c != 'u' )
311
+ . all ( |c| c. to_digit ( base) . is_some ( ) ) ;
312
+
313
+ if valid {
314
+ Some ( format ! ( "0{}{}" , base_char. to_ascii_lowercase( ) , & suffix[ 1 ..] ) )
302
315
} else {
303
316
None
304
317
}
305
318
}
306
319
307
- let token:: Lit { kind, suffix, .. } = lit;
320
+ let token:: Lit { kind, symbol , suffix, .. } = lit;
308
321
match err {
309
322
// `LexerError` is an error, but it was already reported
310
323
// by lexer, so here we don't report it the second time.
@@ -324,7 +337,7 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
324
337
if looks_like_width_suffix ( & [ 'i' , 'u' ] , & suf) {
325
338
// If it looks like a width, try to be helpful.
326
339
sess. emit_err ( InvalidIntLiteralWidth { span, width : suf[ 1 ..] . into ( ) } ) ;
327
- } else if let Some ( fixed) = fix_base_capitalisation ( suf) {
340
+ } else if let Some ( fixed) = fix_base_capitalisation ( symbol . as_str ( ) , suf) {
328
341
sess. emit_err ( InvalidNumLiteralBasePrefix { span, fixed } ) ;
329
342
} else {
330
343
sess. emit_err ( InvalidNumLiteralSuffix { span, suffix : suf. to_string ( ) } ) ;
0 commit comments