about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2024-03-14 00:40:25 +0000
committerEsteban Küber <esteban@kuber.com.ar>2024-03-17 23:35:19 +0000
commitea1883d7b2207d1a0f08046f11ca493803bc8a55 (patch)
tree6fd695414bc60ada3be73bcdd46388d8f6a13ea8
parent6f388ef1fb3964fb83bae5c277f9c83bbde4c76b (diff)
downloadrust-ea1883d7b2207d1a0f08046f11ca493803bc8a55.tar.gz
rust-ea1883d7b2207d1a0f08046f11ca493803bc8a55.zip
Silence redundant error on char literal that was meant to be a string in 2021 edition
-rw-r--r--compiler/rustc_lexer/src/cursor.rs9
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs11
-rw-r--r--tests/ui/lexer/lex-bad-str-literal-as-char-3.rs1
-rw-r--r--tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr14
4 files changed, 20 insertions, 15 deletions
diff --git a/compiler/rustc_lexer/src/cursor.rs b/compiler/rustc_lexer/src/cursor.rs
index 8d8cc9ecc3e..d173c3ac032 100644
--- a/compiler/rustc_lexer/src/cursor.rs
+++ b/compiler/rustc_lexer/src/cursor.rs
@@ -59,6 +59,15 @@ impl<'a> Cursor<'a> {
         iter.next().unwrap_or(EOF_CHAR)
     }
 
+    /// Peeks the third symbol from the input stream without consuming it.
+    pub fn third(&self) -> char {
+        // `.next()` optimizes better than `.nth(1)`
+        let mut iter = self.chars.clone();
+        iter.next();
+        iter.next();
+        iter.next().unwrap_or(EOF_CHAR)
+    }
+
     /// Checks if there is nothing more to consume.
     pub(crate) fn is_eof(&self) -> bool {
         self.chars.as_str().is_empty()
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 5583e49ba60..63b2b47630b 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -698,13 +698,17 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
         let expn_data = prefix_span.ctxt().outer_expn_data();
 
         if expn_data.edition >= Edition::Edition2021 {
+            let mut silence = false;
             // In Rust 2021, this is a hard error.
             let sugg = if prefix == "rb" {
                 Some(errors::UnknownPrefixSugg::UseBr(prefix_span))
             } else if expn_data.is_root() {
                 if self.cursor.first() == '\''
                     && let Some(start) = self.last_lifetime
+                    && self.cursor.third() != '\''
                 {
+                    // An "unclosed `char`" error will be emitted already, silence redundant error.
+                    silence = true;
                     Some(errors::UnknownPrefixSugg::MeantStr {
                         start,
                         end: self.mk_sp(self.pos, self.pos + BytePos(1)),
@@ -715,7 +719,12 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
             } else {
                 None
             };
-            self.dcx().emit_err(errors::UnknownPrefix { span: prefix_span, prefix, sugg });
+            let err = errors::UnknownPrefix { span: prefix_span, prefix, sugg };
+            if silence {
+                self.dcx().create_err(err).delay_as_bug();
+            } else {
+                self.dcx().emit_err(err);
+            }
         } else {
             // Before Rust 2021, only emit a lint for migration.
             self.psess.buffer_lint_with_diagnostic(
diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs
index 2c0eda97853..0ae227da5f1 100644
--- a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs
+++ b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs
@@ -4,5 +4,4 @@
 fn main() {
     println!('hello world');
     //[rust2015,rust2018,rust2021]~^ ERROR unterminated character literal
-    //[rust2021]~^^ ERROR prefix `world` is unknown
 }
diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr
index 4170560cfcb..06f12742667 100644
--- a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr
+++ b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr
@@ -1,15 +1,3 @@
-error: prefix `world` is unknown
-  --> $DIR/lex-bad-str-literal-as-char-3.rs:5:21
-   |
-LL |     println!('hello world');
-   |                     ^^^^^ unknown prefix
-   |
-   = note: prefixed identifiers and literals are reserved since Rust 2021
-help: if you meant to write a string literal, use double quotes
-   |
-LL |     println!("hello world");
-   |              ~           ~
-
 error[E0762]: unterminated character literal
   --> $DIR/lex-bad-str-literal-as-char-3.rs:5:26
    |
@@ -21,6 +9,6 @@ help: if you meant to write a string literal, use double quotes
 LL |     println!("hello world");
    |              ~           ~
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0762`.