about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2023-11-06 21:06:20 +0000
committerEsteban Küber <esteban@kuber.com.ar>2023-11-29 18:47:31 +0000
commited084a93433d214edae3ee739444cbd442baf6fc (patch)
tree28af6542a71aacf116e5a6b51eb6c3166497ef29
parent44fd3b4d4648c9ea2dfa052fe5d3dbb2dfb4f492 (diff)
downloadrust-ed084a93433d214edae3ee739444cbd442baf6fc.tar.gz
rust-ed084a93433d214edae3ee739444cbd442baf6fc.zip
When parsing patterns, bubble all errors except reserved idents that aren't likely to appear in for head or match arm
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs14
-rw-r--r--tests/ui/editions/edition-keywords-2018-2015-parsing.stderr57
-rw-r--r--tests/ui/editions/edition-keywords-2018-2018-parsing.stderr57
-rw-r--r--tests/ui/parser/mut-patterns.rs2
-rw-r--r--tests/ui/parser/mut-patterns.stderr40
-rw-r--r--tests/ui/self/self_type_keyword.stderr58
6 files changed, 221 insertions, 7 deletions
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index ff36ac952ad..ec7c312d03f 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -141,7 +141,19 @@ impl<'a> Parser<'a> {
         };
 
         // Parse the first pattern (`p_0`).
-        let mut first_pat = self.parse_pat_no_top_alt(expected, syntax_loc)?;
+        let mut first_pat = match self.parse_pat_no_top_alt(expected, syntax_loc) {
+            Ok(pat) => pat,
+            Err(mut err)
+                if self.token.is_reserved_ident()
+                    && !self.token.is_keyword(kw::In)
+                    && !self.token.is_keyword(kw::If) =>
+            {
+                err.emit();
+                self.bump();
+                self.mk_pat(self.token.span, PatKind::Wild)
+            }
+            Err(err) => return Err(err),
+        };
         if rc == RecoverComma::Yes {
             self.maybe_recover_unexpected_comma(
                 first_pat.span,
diff --git a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr
index 20a58236855..1a4a94e9733 100644
--- a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr
+++ b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr
@@ -9,5 +9,60 @@ help: escape `async` to use it as an identifier
 LL |     let mut r#async = 1;
    |             ++
 
-error: aborting due to previous error
+error: expected identifier, found keyword `async`
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:26:13
+   |
+LL |     module::async();
+   |             ^^^^^ expected identifier, found keyword
+   |
+help: escape `async` to use it as an identifier
+   |
+LL |     module::r#async();
+   |             ++
+
+error: no rules expected the token `r#async`
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:20:31
+   |
+LL |     r#async = consumes_async!(r#async);
+   |                               ^^^^^^^ no rules expected this token in macro call
+   |
+note: while trying to match `async`
+  --> $DIR/auxiliary/edition-kw-macro-2015.rs:17:6
+   |
+LL |     (async) => (1)
+   |      ^^^^^
+
+error: no rules expected the token `async`
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:21:35
+   |
+LL |     r#async = consumes_async_raw!(async);
+   |                                   ^^^^^ no rules expected this token in macro call
+   |
+note: while trying to match `r#async`
+  --> $DIR/auxiliary/edition-kw-macro-2015.rs:22:6
+   |
+LL |     (r#async) => (1)
+   |      ^^^^^^^
+
+error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
+  --> $DIR/auxiliary/edition-kw-macro-2015.rs:27:23
+   |
+LL |     ($i: ident) => ($i)
+   |                       ^ expected one of `move`, `|`, or `||`
+   |
+  ::: $DIR/edition-keywords-2018-2015-parsing.rs:24:8
+   |
+LL |     if passes_ident!(async) == 1 {}
+   |        -------------------- in this macro invocation
+
+error[E0308]: mismatched types
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:29:33
+   |
+LL |     let _recovery_witness: () = 0;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 6 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr
index e904165a5ce..19eb7ac9823 100644
--- a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr
+++ b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr
@@ -9,5 +9,60 @@ help: escape `async` to use it as an identifier
 LL |     let mut r#async = 1;
    |             ++
 
-error: aborting due to previous error
+error: expected identifier, found keyword `async`
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:26:13
+   |
+LL |     module::async();
+   |             ^^^^^ expected identifier, found keyword
+   |
+help: escape `async` to use it as an identifier
+   |
+LL |     module::r#async();
+   |             ++
+
+error: no rules expected the token `r#async`
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:20:31
+   |
+LL |     r#async = consumes_async!(r#async);
+   |                               ^^^^^^^ no rules expected this token in macro call
+   |
+note: while trying to match `async`
+  --> $DIR/auxiliary/edition-kw-macro-2018.rs:17:6
+   |
+LL |     (async) => (1)
+   |      ^^^^^
+
+error: no rules expected the token `async`
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:21:35
+   |
+LL |     r#async = consumes_async_raw!(async);
+   |                                   ^^^^^ no rules expected this token in macro call
+   |
+note: while trying to match `r#async`
+  --> $DIR/auxiliary/edition-kw-macro-2018.rs:22:6
+   |
+LL |     (r#async) => (1)
+   |      ^^^^^^^
+
+error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
+  --> $DIR/auxiliary/edition-kw-macro-2018.rs:27:23
+   |
+LL |     ($i: ident) => ($i)
+   |                       ^ expected one of `move`, `|`, or `||`
+   |
+  ::: $DIR/edition-keywords-2018-2018-parsing.rs:24:8
+   |
+LL |     if passes_ident!(async) == 1 {}
+   |        -------------------- in this macro invocation
+
+error[E0308]: mismatched types
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:29:33
+   |
+LL |     let _recovery_witness: () = 0;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 6 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/parser/mut-patterns.rs b/tests/ui/parser/mut-patterns.rs
index 8b83d6ab2f8..f2d2df0af29 100644
--- a/tests/ui/parser/mut-patterns.rs
+++ b/tests/ui/parser/mut-patterns.rs
@@ -27,7 +27,7 @@ pub fn main() {
     struct r#yield(u8, u8);
     let mut mut yield(become, await) = r#yield(0, 0);
     //~^ ERROR `mut` on a binding may not be repeated
-    //~| ERROR `mut` must be attached to each individual binding
+    //~| ERROR `mut` must be followed by a named binding
     //~| ERROR expected identifier, found reserved keyword `yield`
     //~| ERROR expected identifier, found reserved keyword `become`
     //~| ERROR expected identifier, found keyword `await`
diff --git a/tests/ui/parser/mut-patterns.stderr b/tests/ui/parser/mut-patterns.stderr
index d91440d7859..6559cf09cdf 100644
--- a/tests/ui/parser/mut-patterns.stderr
+++ b/tests/ui/parser/mut-patterns.stderr
@@ -72,5 +72,43 @@ help: escape `become` to use it as an identifier
 LL |     let mut mut yield(r#become, await) = r#yield(0, 0);
    |                       ++
 
-error: aborting due to 9 previous errors
+error: expected identifier, found keyword `await`
+  --> $DIR/mut-patterns.rs:28:31
+   |
+LL |     let mut mut yield(become, await) = r#yield(0, 0);
+   |                               ^^^^^ expected identifier, found keyword
+   |
+help: escape `await` to use it as an identifier
+   |
+LL |     let mut mut yield(become, r#await) = r#yield(0, 0);
+   |                               ++
+
+error: `mut` must be followed by a named binding
+  --> $DIR/mut-patterns.rs:28:9
+   |
+LL |     let mut mut yield(become, await) = r#yield(0, 0);
+   |         ^^^^^^^^ help: remove the `mut` prefix
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: `mut` must be attached to each individual binding
+  --> $DIR/mut-patterns.rs:37:9
+   |
+LL |     let mut W(mut a, W(b, W(ref c, W(d, B { box f }))))
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `W(mut a, W(mut b, W(ref c, W(mut d, B { box mut f }))))`
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: expected identifier, found `x`
+  --> $DIR/mut-patterns.rs:44:21
+   |
+LL |             let mut $p = 0;
+   |                     ^^ expected identifier
+...
+LL |     foo!(x);
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 13 previous errors
 
diff --git a/tests/ui/self/self_type_keyword.stderr b/tests/ui/self/self_type_keyword.stderr
index cdafae381ac..fed853a7e1f 100644
--- a/tests/ui/self/self_type_keyword.stderr
+++ b/tests/ui/self/self_type_keyword.stderr
@@ -10,6 +10,26 @@ error: expected identifier, found keyword `Self`
 LL |         ref Self => (),
    |             ^^^^ expected identifier, found keyword
 
+error: `mut` must be followed by a named binding
+  --> $DIR/self_type_keyword.rs:16:9
+   |
+LL |         mut Self => (),
+   |         ^^^^ help: remove the `mut` prefix
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: expected identifier, found keyword `Self`
+  --> $DIR/self_type_keyword.rs:19:17
+   |
+LL |         ref mut Self => (),
+   |                 ^^^^ expected identifier, found keyword
+
+error: expected identifier, found keyword `Self`
+  --> $DIR/self_type_keyword.rs:23:15
+   |
+LL |         Foo { Self } => (),
+   |               ^^^^ expected identifier, found keyword
+
 error: expected identifier, found keyword `Self`
   --> $DIR/self_type_keyword.rs:31:26
    |
@@ -34,6 +54,24 @@ error: lifetimes cannot use keyword names
 LL | struct Bar<'Self>;
    |            ^^^^^
 
+error: cannot find macro `Self` in this scope
+  --> $DIR/self_type_keyword.rs:21:9
+   |
+LL |         Self!() => (),
+   |         ^^^^
+
+error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope
+  --> $DIR/self_type_keyword.rs:16:13
+   |
+LL |         mut Self => (),
+   |             ^^^^ not found in this scope
+   |
+note: unit struct `foo::Self` exists but is inaccessible
+  --> $DIR/self_type_keyword.rs:2:3
+   |
+LL |   struct Self;
+   |   ^^^^^^^^^^^^ not accessible
+
 error[E0392]: parameter `'Self` is never used
   --> $DIR/self_type_keyword.rs:6:12
    |
@@ -42,6 +80,22 @@ LL | struct Bar<'Self>;
    |
    = help: consider removing `'Self`, referring to it in a field, or using a marker such as `PhantomData`
 
-error: aborting due to 7 previous errors
+error[E0308]: mismatched types
+  --> $DIR/self_type_keyword.rs:23:9
+   |
+LL |     match 15 {
+   |           -- this expression has type `{integer}`
+...
+LL |         Foo { Self } => (),
+   |         ^^^^^^^^^^^^ expected integer, found `Foo`
+
+error[E0026]: struct `Foo` does not have a field named `Self`
+  --> $DIR/self_type_keyword.rs:23:15
+   |
+LL |         Foo { Self } => (),
+   |               ^^^^ struct `Foo` does not have this field
+
+error: aborting due to 14 previous errors
 
-For more information about this error, try `rustc --explain E0392`.
+Some errors have detailed explanations: E0026, E0308, E0392, E0531.
+For more information about an error, try `rustc --explain E0026`.