@@ -1700,6 +1700,19 @@ impl<'a> Parser<'a> {
1700
1700
s. len ( ) > 1 && s. starts_with ( first_chars) && s[ 1 ..] . chars ( ) . all ( |c| c. is_ascii_digit ( ) )
1701
1701
}
1702
1702
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
+
1703
1716
let token:: Lit { kind, suffix, .. } = lit;
1704
1717
match err {
1705
1718
// `NotLiteral` is not an error by itself, so we don't report
@@ -1724,6 +1737,19 @@ impl<'a> Parser<'a> {
1724
1737
self . struct_span_err ( span, & msg)
1725
1738
. help ( "valid widths are 8, 16, 32, 64 and 128" )
1726
1739
. 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 ( ) ;
1727
1753
} else {
1728
1754
let msg = format ! ( "invalid suffix `{}` for number literal" , suf) ;
1729
1755
self . struct_span_err ( span, & msg)
0 commit comments