@@ -1700,6 +1700,19 @@ impl<'a> Parser<'a> {
17001700 s. len ( ) > 1 && s. starts_with ( first_chars) && s[ 1 ..] . chars ( ) . all ( |c| c. is_ascii_digit ( ) )
17011701 }
17021702
1703+ // Try to lowercase the prefix if it's a valid base prefix.
1704+ fn fix_base_capitalisation ( s : & str ) -> Option < String > {
1705+ if let Some ( stripped) = s. strip_prefix ( "B" ) {
1706+ Some ( format ! ( "0b{stripped}" ) )
1707+ } else if let Some ( stripped) = s. strip_prefix ( "O" ) {
1708+ Some ( format ! ( "0o{stripped}" ) )
1709+ } else if let Some ( stripped) = s. strip_prefix ( "X" ) {
1710+ Some ( format ! ( "0x{stripped}" ) )
1711+ } else {
1712+ None
1713+ }
1714+ }
1715+
17031716 let token:: Lit { kind, suffix, .. } = lit;
17041717 match err {
17051718 // `NotLiteral` is not an error by itself, so we don't report
@@ -1724,6 +1737,19 @@ impl<'a> Parser<'a> {
17241737 self . struct_span_err ( span, & msg)
17251738 . help ( "valid widths are 8, 16, 32, 64 and 128" )
17261739 . emit ( ) ;
1740+ } else if let Some ( fixed) = fix_base_capitalisation ( suf) {
1741+ let msg = format ! ( "invalid suffix `{}` for number literal" , suf) ;
1742+
1743+ self . struct_span_err ( span, & msg)
1744+ . span_label ( span, format ! ( "invalid suffix `{}`" , suf) )
1745+ . help ( "base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase" )
1746+ . span_suggestion (
1747+ span,
1748+ "try making the prefix lowercase" ,
1749+ fixed,
1750+ Applicability :: MaybeIncorrect ,
1751+ )
1752+ . emit ( ) ;
17271753 } else {
17281754 let msg = format ! ( "invalid suffix `{}` for number literal" , suf) ;
17291755 self . struct_span_err ( span, & msg)
0 commit comments