diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 693dd0051dad1..0115d498a7fb8 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1700,6 +1700,19 @@ impl<'a> Parser<'a> { s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit()) } + // Try to lowercase the prefix if it's a valid base prefix. + fn fix_base_capitalisation(s: &str) -> Option { + if let Some(stripped) = s.strip_prefix("B") { + Some(format!("0b{stripped}")) + } else if let Some(stripped) = s.strip_prefix("O") { + Some(format!("0o{stripped}")) + } else if let Some(stripped) = s.strip_prefix("X") { + Some(format!("0x{stripped}")) + } else { + None + } + } + let token::Lit { kind, suffix, .. } = lit; match err { // `NotLiteral` is not an error by itself, so we don't report @@ -1724,6 +1737,18 @@ impl<'a> Parser<'a> { self.struct_span_err(span, &msg) .help("valid widths are 8, 16, 32, 64 and 128") .emit(); + } else if let Some(fixed) = fix_base_capitalisation(suf) { + let msg = "invalid base prefix for number literal"; + + self.struct_span_err(span, &msg) + .note("base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase") + .span_suggestion( + span, + "try making the prefix lowercase", + fixed, + Applicability::MaybeIncorrect, + ) + .emit(); } else { let msg = format!("invalid suffix `{}` for number literal", suf); self.struct_span_err(span, &msg) diff --git a/src/test/ui/numeric/uppercase-base-prefix.fixed b/src/test/ui/numeric/uppercase-base-prefix.fixed new file mode 100644 index 0000000000000..1b1c837ec5040 --- /dev/null +++ b/src/test/ui/numeric/uppercase-base-prefix.fixed @@ -0,0 +1,77 @@ +// run-rustfix +// Checks that integers with an uppercase base prefix (0B, 0X, 0O) have a nice error +#![allow(unused_variables)] + +fn main() { + let a = 0xABCDEF; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0xABCDEF + + let b = 0o755; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0o755 + + let c = 0b10101010; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0b10101010 + + let d = 0xABC_DEF; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0xABC_DEF + + let e = 0o7_55; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0o7_55 + + let f = 0b1010_1010; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0b1010_1010 + + let g = 0xABC_DEF_u64; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0xABC_DEF_u64 + + let h = 0o7_55_u32; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0o7_55_u32 + + let i = 0b1010_1010_u8; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0b1010_1010_u8 + // + let j = 0xABCDEFu64; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0xABCDEFu64 + + let k = 0o755u32; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0o755u32 + + let l = 0b10101010u8; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0b10101010u8 +} diff --git a/src/test/ui/numeric/uppercase-base-prefix.rs b/src/test/ui/numeric/uppercase-base-prefix.rs new file mode 100644 index 0000000000000..233d553da6585 --- /dev/null +++ b/src/test/ui/numeric/uppercase-base-prefix.rs @@ -0,0 +1,77 @@ +// run-rustfix +// Checks that integers with an uppercase base prefix (0B, 0X, 0O) have a nice error +#![allow(unused_variables)] + +fn main() { + let a = 0XABCDEF; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0xABCDEF + + let b = 0O755; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0o755 + + let c = 0B10101010; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0b10101010 + + let d = 0XABC_DEF; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0xABC_DEF + + let e = 0O7_55; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0o7_55 + + let f = 0B1010_1010; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0b1010_1010 + + let g = 0XABC_DEF_u64; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0xABC_DEF_u64 + + let h = 0O7_55_u32; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0o7_55_u32 + + let i = 0B1010_1010_u8; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0b1010_1010_u8 + // + let j = 0XABCDEFu64; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0xABCDEFu64 + + let k = 0O755u32; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0o755u32 + + let l = 0B10101010u8; + //~^ ERROR invalid base prefix for number literal + //~| NOTE base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + //~| HELP try making the prefix lowercase + //~| SUGGESTION 0b10101010u8 +} diff --git a/src/test/ui/numeric/uppercase-base-prefix.stderr b/src/test/ui/numeric/uppercase-base-prefix.stderr new file mode 100644 index 0000000000000..4ba8d5224b3e6 --- /dev/null +++ b/src/test/ui/numeric/uppercase-base-prefix.stderr @@ -0,0 +1,98 @@ +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:6:13 + | +LL | let a = 0XABCDEF; + | ^^^^^^^^ help: try making the prefix lowercase (notice the capitalization): `0xABCDEF` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:12:13 + | +LL | let b = 0O755; + | ^^^^^ help: try making the prefix lowercase (notice the capitalization): `0o755` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:18:13 + | +LL | let c = 0B10101010; + | ^^^^^^^^^^ help: try making the prefix lowercase: `0b10101010` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:24:13 + | +LL | let d = 0XABC_DEF; + | ^^^^^^^^^ help: try making the prefix lowercase (notice the capitalization): `0xABC_DEF` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:30:13 + | +LL | let e = 0O7_55; + | ^^^^^^ help: try making the prefix lowercase (notice the capitalization): `0o7_55` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:36:13 + | +LL | let f = 0B1010_1010; + | ^^^^^^^^^^^ help: try making the prefix lowercase: `0b1010_1010` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:42:13 + | +LL | let g = 0XABC_DEF_u64; + | ^^^^^^^^^^^^^ help: try making the prefix lowercase (notice the capitalization): `0xABC_DEF_u64` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:48:13 + | +LL | let h = 0O7_55_u32; + | ^^^^^^^^^^ help: try making the prefix lowercase (notice the capitalization): `0o7_55_u32` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:54:13 + | +LL | let i = 0B1010_1010_u8; + | ^^^^^^^^^^^^^^ help: try making the prefix lowercase: `0b1010_1010_u8` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:60:13 + | +LL | let j = 0XABCDEFu64; + | ^^^^^^^^^^^ help: try making the prefix lowercase (notice the capitalization): `0xABCDEFu64` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:66:13 + | +LL | let k = 0O755u32; + | ^^^^^^^^ help: try making the prefix lowercase (notice the capitalization): `0o755u32` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: invalid base prefix for number literal + --> $DIR/uppercase-base-prefix.rs:72:13 + | +LL | let l = 0B10101010u8; + | ^^^^^^^^^^^^ help: try making the prefix lowercase: `0b10101010u8` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: aborting due to 12 previous errors +