about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2024-03-30 02:50:17 +0000
committerEsteban Küber <esteban@kuber.com.ar>2024-04-07 17:22:34 +0000
commite572a194bf76957fa41495aa13f9925df6e632b2 (patch)
tree7361b7ba5b5028b8407e9bd87d24a5507e3e1cf4
parente78913baef70895c966f0456ad16086a6a9aa37b (diff)
downloadrust-e572a194bf76957fa41495aa13f9925df6e632b2.tar.gz
rust-e572a194bf76957fa41495aa13f9925df6e632b2.zip
Fix invalid silencing of parsing error
Given

```rust
macro_rules! a {
    ( ) => {
        impl<'b> c for d {
            e::<f'g>
        }
    };
}
```

ensure an error is emitted.

Fix #123079.
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs20
-rw-r--r--tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.rs9
-rw-r--r--tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.stderr14
-rw-r--r--tests/ui/lexer/lex-bad-str-literal-as-char-3.rs3
-rw-r--r--tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr14
-rw-r--r--tests/ui/lexer/lex-bad-str-literal-as-char-4.rs9
-rw-r--r--tests/ui/lexer/lex-bad-str-literal-as-char-4.stderr26
7 files changed, 80 insertions, 15 deletions
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 69b48bf0aff..f381995d346 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -698,7 +698,6 @@ 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))
@@ -706,25 +705,20 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
                 if self.cursor.first() == '\''
                     && let Some(start) = self.last_lifetime
                     && self.cursor.third() != '\''
+                    && let end = self.mk_sp(self.pos, self.pos + BytePos(1))
+                    && !self.psess.source_map().is_multiline(start.until(end))
                 {
-                    // 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)),
-                    })
+                    // FIXME: An "unclosed `char`" error will be emitted already in some cases,
+                    // but it's hard to silence this error while not also silencing important cases
+                    // too. We should use the error stashing machinery instead.
+                    Some(errors::UnknownPrefixSugg::MeantStr { start, end })
                 } else {
                     Some(errors::UnknownPrefixSugg::Whitespace(prefix_span.shrink_to_hi()))
                 }
             } else {
                 None
             };
-            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);
-            }
+            self.dcx().emit_err(errors::UnknownPrefix { span: prefix_span, prefix, sugg });
         } else {
             // Before Rust 2021, only emit a lint for migration.
             self.psess.buffer_lint_with_diagnostic(
diff --git a/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.rs b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.rs
new file mode 100644
index 00000000000..caae48dfd3b
--- /dev/null
+++ b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.rs
@@ -0,0 +1,9 @@
+//@ edition:2021
+macro_rules! a {
+    ( ) => {
+        impl<'b> c for d {
+            e::<f'g> //~ ERROR prefix `f` is unknown
+        }
+    };
+}
+fn main() {}
diff --git a/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.stderr b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.stderr
new file mode 100644
index 00000000000..ecce2c66504
--- /dev/null
+++ b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.stderr
@@ -0,0 +1,14 @@
+error: prefix `f` is unknown
+  --> $DIR/dont-ice-on-invalid-lifetime-in-macro-definition.rs:5:17
+   |
+LL |             e::<f'g>
+   |                 ^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+   |
+LL |             e::<f 'g>
+   |                  +
+
+error: aborting due to 1 previous error
+
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 0ae227da5f1..52781d9c6d8 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
@@ -3,5 +3,6 @@
 //@[rust2021] edition:2021
 fn main() {
     println!('hello world');
-    //[rust2015,rust2018,rust2021]~^ ERROR unterminated character literal
+    //~^ 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 06f12742667..4170560cfcb 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,3 +1,15 @@
+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
    |
@@ -9,6 +21,6 @@ help: if you meant to write a string literal, use double quotes
 LL |     println!("hello world");
    |              ~           ~
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0762`.
diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-4.rs b/tests/ui/lexer/lex-bad-str-literal-as-char-4.rs
new file mode 100644
index 00000000000..f0c7ad8f82b
--- /dev/null
+++ b/tests/ui/lexer/lex-bad-str-literal-as-char-4.rs
@@ -0,0 +1,9 @@
+//@edition:2021
+macro_rules! foo {
+    () => {
+        println!('hello world');
+        //~^ ERROR unterminated character literal
+        //~| ERROR prefix `world` is unknown
+    }
+}
+fn main() {}
diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-4.stderr b/tests/ui/lexer/lex-bad-str-literal-as-char-4.stderr
new file mode 100644
index 00000000000..af42b5b7f7b
--- /dev/null
+++ b/tests/ui/lexer/lex-bad-str-literal-as-char-4.stderr
@@ -0,0 +1,26 @@
+error: prefix `world` is unknown
+  --> $DIR/lex-bad-str-literal-as-char-4.rs:4:25
+   |
+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-4.rs:4:30
+   |
+LL |         println!('hello world');
+   |                              ^^^
+   |
+help: if you meant to write a string literal, use double quotes
+   |
+LL |         println!("hello world");
+   |                  ~           ~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0762`.