about summary refs log tree commit diff
path: root/compiler/rustc_session/src/errors.rs
diff options
context:
space:
mode:
authorCassaundra Smith <cass@cassaundra.org>2022-12-01 19:17:03 -0800
committerCassaundra Smith <cass@cassaundra.org>2022-12-12 19:32:12 -0800
commit52a9280fb249f2dfbc879ae32b1823203822fbec (patch)
treee57ab41f31179a9616bb09d8999c88facca45903 /compiler/rustc_session/src/errors.rs
parent2585bcea0bc2a9c42a4be2c1eba5c61137f2b167 (diff)
downloadrust-52a9280fb249f2dfbc879ae32b1823203822fbec.tar.gz
rust-52a9280fb249f2dfbc879ae32b1823203822fbec.zip
Refine when invalid prefix case error arises
Fix cases where the "invalid base prefix for number literal" error arises with
suffixes that look erroneously capitalized but which are in fact invalid.
Diffstat (limited to 'compiler/rustc_session/src/errors.rs')
-rw-r--r--compiler/rustc_session/src/errors.rs33
1 files changed, 23 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() });