Skip to content

Commit ed084a9

Browse files
committed
When parsing patterns, bubble all errors except reserved idents that aren't likely to appear in for head or match arm
1 parent 44fd3b4 commit ed084a9

File tree

6 files changed

+221
-7
lines changed

6 files changed

+221
-7
lines changed

compiler/rustc_parse/src/parser/pat.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,19 @@ impl<'a> Parser<'a> {
141141
};
142142

143143
// Parse the first pattern (`p_0`).
144-
let mut first_pat = self.parse_pat_no_top_alt(expected, syntax_loc)?;
144+
let mut first_pat = match self.parse_pat_no_top_alt(expected, syntax_loc) {
145+
Ok(pat) => pat,
146+
Err(mut err)
147+
if self.token.is_reserved_ident()
148+
&& !self.token.is_keyword(kw::In)
149+
&& !self.token.is_keyword(kw::If) =>
150+
{
151+
err.emit();
152+
self.bump();
153+
self.mk_pat(self.token.span, PatKind::Wild)
154+
}
155+
Err(err) => return Err(err),
156+
};
145157
if rc == RecoverComma::Yes {
146158
self.maybe_recover_unexpected_comma(
147159
first_pat.span,

tests/ui/editions/edition-keywords-2018-2015-parsing.stderr

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,60 @@ help: escape `async` to use it as an identifier
99
LL | let mut r#async = 1;
1010
| ++
1111

12-
error: aborting due to previous error
12+
error: expected identifier, found keyword `async`
13+
--> $DIR/edition-keywords-2018-2015-parsing.rs:26:13
14+
|
15+
LL | module::async();
16+
| ^^^^^ expected identifier, found keyword
17+
|
18+
help: escape `async` to use it as an identifier
19+
|
20+
LL | module::r#async();
21+
| ++
22+
23+
error: no rules expected the token `r#async`
24+
--> $DIR/edition-keywords-2018-2015-parsing.rs:20:31
25+
|
26+
LL | r#async = consumes_async!(r#async);
27+
| ^^^^^^^ no rules expected this token in macro call
28+
|
29+
note: while trying to match `async`
30+
--> $DIR/auxiliary/edition-kw-macro-2015.rs:17:6
31+
|
32+
LL | (async) => (1)
33+
| ^^^^^
34+
35+
error: no rules expected the token `async`
36+
--> $DIR/edition-keywords-2018-2015-parsing.rs:21:35
37+
|
38+
LL | r#async = consumes_async_raw!(async);
39+
| ^^^^^ no rules expected this token in macro call
40+
|
41+
note: while trying to match `r#async`
42+
--> $DIR/auxiliary/edition-kw-macro-2015.rs:22:6
43+
|
44+
LL | (r#async) => (1)
45+
| ^^^^^^^
46+
47+
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
48+
--> $DIR/auxiliary/edition-kw-macro-2015.rs:27:23
49+
|
50+
LL | ($i: ident) => ($i)
51+
| ^ expected one of `move`, `|`, or `||`
52+
|
53+
::: $DIR/edition-keywords-2018-2015-parsing.rs:24:8
54+
|
55+
LL | if passes_ident!(async) == 1 {}
56+
| -------------------- in this macro invocation
57+
58+
error[E0308]: mismatched types
59+
--> $DIR/edition-keywords-2018-2015-parsing.rs:29:33
60+
|
61+
LL | let _recovery_witness: () = 0;
62+
| -- ^ expected `()`, found integer
63+
| |
64+
| expected due to this
65+
66+
error: aborting due to 6 previous errors
1367

68+
For more information about this error, try `rustc --explain E0308`.

tests/ui/editions/edition-keywords-2018-2018-parsing.stderr

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,60 @@ help: escape `async` to use it as an identifier
99
LL | let mut r#async = 1;
1010
| ++
1111

12-
error: aborting due to previous error
12+
error: expected identifier, found keyword `async`
13+
--> $DIR/edition-keywords-2018-2018-parsing.rs:26:13
14+
|
15+
LL | module::async();
16+
| ^^^^^ expected identifier, found keyword
17+
|
18+
help: escape `async` to use it as an identifier
19+
|
20+
LL | module::r#async();
21+
| ++
22+
23+
error: no rules expected the token `r#async`
24+
--> $DIR/edition-keywords-2018-2018-parsing.rs:20:31
25+
|
26+
LL | r#async = consumes_async!(r#async);
27+
| ^^^^^^^ no rules expected this token in macro call
28+
|
29+
note: while trying to match `async`
30+
--> $DIR/auxiliary/edition-kw-macro-2018.rs:17:6
31+
|
32+
LL | (async) => (1)
33+
| ^^^^^
34+
35+
error: no rules expected the token `async`
36+
--> $DIR/edition-keywords-2018-2018-parsing.rs:21:35
37+
|
38+
LL | r#async = consumes_async_raw!(async);
39+
| ^^^^^ no rules expected this token in macro call
40+
|
41+
note: while trying to match `r#async`
42+
--> $DIR/auxiliary/edition-kw-macro-2018.rs:22:6
43+
|
44+
LL | (r#async) => (1)
45+
| ^^^^^^^
46+
47+
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
48+
--> $DIR/auxiliary/edition-kw-macro-2018.rs:27:23
49+
|
50+
LL | ($i: ident) => ($i)
51+
| ^ expected one of `move`, `|`, or `||`
52+
|
53+
::: $DIR/edition-keywords-2018-2018-parsing.rs:24:8
54+
|
55+
LL | if passes_ident!(async) == 1 {}
56+
| -------------------- in this macro invocation
57+
58+
error[E0308]: mismatched types
59+
--> $DIR/edition-keywords-2018-2018-parsing.rs:29:33
60+
|
61+
LL | let _recovery_witness: () = 0;
62+
| -- ^ expected `()`, found integer
63+
| |
64+
| expected due to this
65+
66+
error: aborting due to 6 previous errors
1367

68+
For more information about this error, try `rustc --explain E0308`.

tests/ui/parser/mut-patterns.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub fn main() {
2727
struct r#yield(u8, u8);
2828
let mut mut yield(become, await) = r#yield(0, 0);
2929
//~^ ERROR `mut` on a binding may not be repeated
30-
//~| ERROR `mut` must be attached to each individual binding
30+
//~| ERROR `mut` must be followed by a named binding
3131
//~| ERROR expected identifier, found reserved keyword `yield`
3232
//~| ERROR expected identifier, found reserved keyword `become`
3333
//~| ERROR expected identifier, found keyword `await`

tests/ui/parser/mut-patterns.stderr

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,43 @@ help: escape `become` to use it as an identifier
7272
LL | let mut mut yield(r#become, await) = r#yield(0, 0);
7373
| ++
7474

75-
error: aborting due to 9 previous errors
75+
error: expected identifier, found keyword `await`
76+
--> $DIR/mut-patterns.rs:28:31
77+
|
78+
LL | let mut mut yield(become, await) = r#yield(0, 0);
79+
| ^^^^^ expected identifier, found keyword
80+
|
81+
help: escape `await` to use it as an identifier
82+
|
83+
LL | let mut mut yield(become, r#await) = r#yield(0, 0);
84+
| ++
85+
86+
error: `mut` must be followed by a named binding
87+
--> $DIR/mut-patterns.rs:28:9
88+
|
89+
LL | let mut mut yield(become, await) = r#yield(0, 0);
90+
| ^^^^^^^^ help: remove the `mut` prefix
91+
|
92+
= note: `mut` may be followed by `variable` and `variable @ pattern`
93+
94+
error: `mut` must be attached to each individual binding
95+
--> $DIR/mut-patterns.rs:37:9
96+
|
97+
LL | let mut W(mut a, W(b, W(ref c, W(d, B { box f }))))
98+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `W(mut a, W(mut b, W(ref c, W(mut d, B { box mut f }))))`
99+
|
100+
= note: `mut` may be followed by `variable` and `variable @ pattern`
101+
102+
error: expected identifier, found `x`
103+
--> $DIR/mut-patterns.rs:44:21
104+
|
105+
LL | let mut $p = 0;
106+
| ^^ expected identifier
107+
...
108+
LL | foo!(x);
109+
| ------- in this macro invocation
110+
|
111+
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
112+
113+
error: aborting due to 13 previous errors
76114

tests/ui/self/self_type_keyword.stderr

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,26 @@ error: expected identifier, found keyword `Self`
1010
LL | ref Self => (),
1111
| ^^^^ expected identifier, found keyword
1212

13+
error: `mut` must be followed by a named binding
14+
--> $DIR/self_type_keyword.rs:16:9
15+
|
16+
LL | mut Self => (),
17+
| ^^^^ help: remove the `mut` prefix
18+
|
19+
= note: `mut` may be followed by `variable` and `variable @ pattern`
20+
21+
error: expected identifier, found keyword `Self`
22+
--> $DIR/self_type_keyword.rs:19:17
23+
|
24+
LL | ref mut Self => (),
25+
| ^^^^ expected identifier, found keyword
26+
27+
error: expected identifier, found keyword `Self`
28+
--> $DIR/self_type_keyword.rs:23:15
29+
|
30+
LL | Foo { Self } => (),
31+
| ^^^^ expected identifier, found keyword
32+
1333
error: expected identifier, found keyword `Self`
1434
--> $DIR/self_type_keyword.rs:31:26
1535
|
@@ -34,6 +54,24 @@ error: lifetimes cannot use keyword names
3454
LL | struct Bar<'Self>;
3555
| ^^^^^
3656

57+
error: cannot find macro `Self` in this scope
58+
--> $DIR/self_type_keyword.rs:21:9
59+
|
60+
LL | Self!() => (),
61+
| ^^^^
62+
63+
error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope
64+
--> $DIR/self_type_keyword.rs:16:13
65+
|
66+
LL | mut Self => (),
67+
| ^^^^ not found in this scope
68+
|
69+
note: unit struct `foo::Self` exists but is inaccessible
70+
--> $DIR/self_type_keyword.rs:2:3
71+
|
72+
LL | struct Self;
73+
| ^^^^^^^^^^^^ not accessible
74+
3775
error[E0392]: parameter `'Self` is never used
3876
--> $DIR/self_type_keyword.rs:6:12
3977
|
@@ -42,6 +80,22 @@ LL | struct Bar<'Self>;
4280
|
4381
= help: consider removing `'Self`, referring to it in a field, or using a marker such as `PhantomData`
4482

45-
error: aborting due to 7 previous errors
83+
error[E0308]: mismatched types
84+
--> $DIR/self_type_keyword.rs:23:9
85+
|
86+
LL | match 15 {
87+
| -- this expression has type `{integer}`
88+
...
89+
LL | Foo { Self } => (),
90+
| ^^^^^^^^^^^^ expected integer, found `Foo`
91+
92+
error[E0026]: struct `Foo` does not have a field named `Self`
93+
--> $DIR/self_type_keyword.rs:23:15
94+
|
95+
LL | Foo { Self } => (),
96+
| ^^^^ struct `Foo` does not have this field
97+
98+
error: aborting due to 14 previous errors
4699

47-
For more information about this error, try `rustc --explain E0392`.
100+
Some errors have detailed explanations: E0026, E0308, E0392, E0531.
101+
For more information about an error, try `rustc --explain E0026`.

0 commit comments

Comments
 (0)