about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Huss <eric@huss.org>2022-01-31 20:12:55 -0800
committerGitHub <noreply@github.com>2022-01-31 20:12:55 -0800
commitd7c0b4f706ca1f093845faab62100cec29769bb0 (patch)
treeba2eb169f800e11b03b890fdbc2302ec8b1e423a
parent5159c013b0a9771c3c83fb23f8ce4711c0bd4954 (diff)
parentec3b711a4bcc8cb3af34b2cdf1ad110eef5981f9 (diff)
downloadrust-d7c0b4f706ca1f093845faab62100cec29769bb0.tar.gz
rust-d7c0b4f706ca1f093845faab62100cec29769bb0.zip
Rollup merge of #93019 - 5225225:uppercase-suffix, r=wesleywiser
If an integer is entered with an upper-case base prefix (0Xbeef, 0O755, 0B1010), suggest to make it lowercase

The current error for this case isn't really great, it just complains about the whole thing past the `0` being an invalid suffix.
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs25
-rw-r--r--src/test/ui/numeric/uppercase-base-prefix.fixed77
-rw-r--r--src/test/ui/numeric/uppercase-base-prefix.rs77
-rw-r--r--src/test/ui/numeric/uppercase-base-prefix.stderr98
4 files changed, 277 insertions, 0 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 693dd0051da..0115d498a7f 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<String> {
+            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 00000000000..1b1c837ec50
--- /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 00000000000..233d553da65
--- /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 00000000000..4ba8d5224b3
--- /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
+