about summary refs log tree commit diff
path: root/compiler/rustc_session/src/errors.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_session/src/errors.rs')
-rw-r--r--compiler/rustc_session/src/errors.rs53
1 files changed, 31 insertions, 22 deletions
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 91cc31cc126..25d84506efa 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -129,10 +129,10 @@ pub struct FileIsNotWriteable<'a> {
 
 #[derive(Diagnostic)]
 #[diag(session_crate_name_does_not_match)]
-pub struct CrateNameDoesNotMatch<'a> {
+pub struct CrateNameDoesNotMatch {
     #[primary_span]
     pub span: Span,
-    pub s: &'a str,
+    pub s: Symbol,
     pub name: Symbol,
 }
 
@@ -151,11 +151,11 @@ pub struct CrateNameEmpty {
 
 #[derive(Diagnostic)]
 #[diag(session_invalid_character_in_create_name)]
-pub struct InvalidCharacterInCrateName<'a> {
+pub struct InvalidCharacterInCrateName {
     #[primary_span]
     pub span: Option<Span>,
     pub character: char,
-    pub crate_name: &'a str,
+    pub crate_name: Symbol,
 }
 
 #[derive(Subdiagnostic)]
@@ -197,12 +197,12 @@ pub enum UnleashedFeatureHelp {
 
 #[derive(Diagnostic)]
 #[diag(session_invalid_literal_suffix)]
-pub(crate) struct InvalidLiteralSuffix {
+pub(crate) struct InvalidLiteralSuffix<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
     // FIXME(#100717)
-    pub kind: String,
+    pub kind: &'a str,
     pub suffix: Symbol,
 }
 
@@ -291,40 +291,49 @@ 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.
         LitError::LexerError => {}
         LitError::InvalidSuffix => {
             if let Some(suffix) = suffix {
-                sess.emit_err(InvalidLiteralSuffix {
-                    span,
-                    kind: format!("{}", kind.descr()),
-                    suffix,
-                });
+                sess.emit_err(InvalidLiteralSuffix { span, kind: kind.descr(), suffix });
             }
         }
         LitError::InvalidIntSuffix => {
             let suf = suffix.expect("suffix error with no suffix");
             let suf = suf.as_str();
-            if looks_like_width_suffix(&['i', 'u'], &suf) {
+            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() });