about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_session/src/errors.rs33
-rw-r--r--src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.rs34
-rw-r--r--src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.stderr50
3 files changed, 107 insertions, 10 deletions
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 2f7055e3cc5..268849ecd59 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -291,20 +291,33 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
         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}"))
+    // Try to lowercase the prefix if the prefix and suffix are valid.
+    fn fix_base_capitalisation(prefix: &str, suffix: &str) -> Option<String> {
+        let mut chars = suffix.chars();
+
+        let base_char = chars.next().unwrap();
+        let base = match base_char {
+            'B' => 2,
+            'O' => 8,
+            'X' => 16,
+            _ => return None,
+        };
+
+        // check that the suffix contains only base-appropriate characters
+        let valid = prefix == "0"
+            && chars
+                .filter(|c| *c != '_')
+                .take_while(|c| *c != 'i' && *c != 'u')
+                .all(|c| c.to_digit(base).is_some());
+
+        if valid {
+            Some(format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..]))
         } else {
             None
         }
     }
 
-    let token::Lit { kind, suffix, .. } = lit;
+    let token::Lit { kind, symbol, suffix, .. } = lit;
     match err {
         // `LexerError` is an error, but it was already reported
         // 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:
             if looks_like_width_suffix(&['i', 'u'], &suf) {
                 // If it looks like a width, try to be helpful.
                 sess.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() });
-            } else if let Some(fixed) = fix_base_capitalisation(suf) {
+            } else if let Some(fixed) = fix_base_capitalisation(symbol.as_str(), suf) {
                 sess.emit_err(InvalidNumLiteralBasePrefix { span, fixed });
             } else {
                 sess.emit_err(InvalidNumLiteralSuffix { span, suffix: suf.to_string() });
diff --git a/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.rs b/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.rs
new file mode 100644
index 00000000000..f00cde4a74c
--- /dev/null
+++ b/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.rs
@@ -0,0 +1,34 @@
+// Checks that integers with seeming uppercase base prefixes do not get bogus capitalization
+// suggestions.
+
+fn main() {
+    _ = 123X1a3;
+    //~^ ERROR invalid suffix `X1a3` for number literal
+    //~| NOTE invalid suffix `X1a3`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+    _ = 456O123;
+    //~^ ERROR invalid suffix `O123` for number literal
+    //~| NOTE invalid suffix `O123`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+    _ = 789B101;
+    //~^ ERROR invalid suffix `B101` for number literal
+    //~| NOTE invalid suffix `B101`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+    _ = 0XYZ;
+    //~^ ERROR invalid suffix `XYZ` for number literal
+    //~| NOTE invalid suffix `XYZ`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+    _ = 0OPQ;
+    //~^ ERROR invalid suffix `OPQ` for number literal
+    //~| NOTE invalid suffix `OPQ`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+    _ = 0BCD;
+    //~^ ERROR invalid suffix `BCD` for number literal
+    //~| NOTE invalid suffix `BCD`
+    //~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+}
diff --git a/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.stderr b/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.stderr
new file mode 100644
index 00000000000..380c16ca789
--- /dev/null
+++ b/src/test/ui/numeric/uppercase-base-prefix-invalid-no-fix.stderr
@@ -0,0 +1,50 @@
+error: invalid suffix `X1a3` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:5:9
+   |
+LL |     _ = 123X1a3;
+   |         ^^^^^^^ invalid suffix `X1a3`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `O123` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:10:9
+   |
+LL |     _ = 456O123;
+   |         ^^^^^^^ invalid suffix `O123`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `B101` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:15:9
+   |
+LL |     _ = 789B101;
+   |         ^^^^^^^ invalid suffix `B101`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `XYZ` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:20:9
+   |
+LL |     _ = 0XYZ;
+   |         ^^^^ invalid suffix `XYZ`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `OPQ` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:25:9
+   |
+LL |     _ = 0OPQ;
+   |         ^^^^ invalid suffix `OPQ`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `BCD` for number literal
+  --> $DIR/uppercase-base-prefix-invalid-no-fix.rs:30:9
+   |
+LL |     _ = 0BCD;
+   |         ^^^^ invalid suffix `BCD`
+   |
+   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: aborting due to 6 previous errors
+