Skip to content

Commit 9d2a9d9

Browse files
committed
Fix last let_chains blocker
1 parent c461f7a commit 9d2a9d9

File tree

9 files changed

+827
-301
lines changed

9 files changed

+827
-301
lines changed

compiler/rustc_parse/src/parser/expr.rs

+24-8
Original file line numberDiff line numberDiff line change
@@ -1393,7 +1393,9 @@ impl<'a> Parser<'a> {
13931393
self.parse_yield_expr(attrs)
13941394
} else if self.is_do_yeet() {
13951395
self.parse_yeet_expr(attrs)
1396-
} else if self.eat_keyword(kw::Let) {
1396+
} else if self.check_keyword(kw::Let) {
1397+
self.manage_let_chains_context();
1398+
self.bump();
13971399
self.parse_let_expr(attrs)
13981400
} else if self.eat_keyword(kw::Underscore) {
13991401
Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore, attrs))
@@ -2355,16 +2357,30 @@ impl<'a> Parser<'a> {
23552357
Ok(cond)
23562358
}
23572359

2360+
// Checks if `let` is in an invalid position like `let x = let y = 1;` or
2361+
// if the current `let` is in a let_chains context but nested in another
2362+
// expression like `if let Some(_) = _opt && [1, 2, 3][let _ = ()] = 1`.
2363+
//
2364+
// This method expects that the current token is `let`.
2365+
fn manage_let_chains_context(&mut self) {
2366+
debug_assert!(matches!(self.token.kind, TokenKind::Ident(kw::Let, _)));
2367+
let is_in_a_let_chains_context_but_nested_in_other_expr = self.let_expr_allowed
2368+
&& !matches!(
2369+
self.prev_token.kind,
2370+
TokenKind::AndAnd
2371+
| TokenKind::CloseDelim(Delimiter::Brace)
2372+
| TokenKind::Ident(kw::If, _)
2373+
| TokenKind::Ident(kw::While, _)
2374+
);
2375+
if !self.let_expr_allowed || is_in_a_let_chains_context_but_nested_in_other_expr {
2376+
self.struct_span_err(self.token.span, "expected expression, found `let` statement")
2377+
.emit();
2378+
}
2379+
}
2380+
23582381
/// Parses a `let $pat = $expr` pseudo-expression.
23592382
/// The `let` token has already been eaten.
23602383
fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
2361-
if !self.let_expr_allowed {
2362-
self.struct_span_err(
2363-
self.prev_token.span,
2364-
"expected expression, found `let` statement",
2365-
)
2366-
.emit();
2367-
}
23682384
let lo = self.prev_token.span;
23692385
let pat = self.parse_pat_allow_top_alt(
23702386
None,

src/test/ui/rfc-2294-if-let-guard/feature-gate.rs

+7
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ fn _if_let_guard() {
99

1010
() if (let 0 = 1) => {}
1111
//~^ ERROR `let` expressions in this position are unstable
12+
//~| ERROR expected expression, found `let` statement
1213

1314
() if (((let 0 = 1))) => {}
1415
//~^ ERROR `let` expressions in this position are unstable
16+
//~| ERROR expected expression, found `let` statement
1517

1618
() if true && let 0 = 1 => {}
1719
//~^ ERROR `if let` guards are experimental
@@ -23,13 +25,17 @@ fn _if_let_guard() {
2325

2426
() if (let 0 = 1) && true => {}
2527
//~^ ERROR `let` expressions in this position are unstable
28+
//~| ERROR expected expression, found `let` statement
2629

2730
() if true && (let 0 = 1) => {}
2831
//~^ ERROR `let` expressions in this position are unstable
32+
//~| ERROR expected expression, found `let` statement
2933

3034
() if (let 0 = 1) && (let 0 = 1) => {}
3135
//~^ ERROR `let` expressions in this position are unstable
3236
//~| ERROR `let` expressions in this position are unstable
37+
//~| ERROR expected expression, found `let` statement
38+
//~| ERROR expected expression, found `let` statement
3339

3440
() if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
3541
//~^ ERROR `if let` guards are experimental
@@ -38,6 +44,7 @@ fn _if_let_guard() {
3844
//~| ERROR `let` expressions in this position are unstable
3945
//~| ERROR `let` expressions in this position are unstable
4046
//~| ERROR `let` expressions in this position are unstable
47+
//~| ERROR expected expression, found `let` statement
4148

4249
() if let Range { start: _, end: _ } = (true..true) && false => {}
4350
//~^ ERROR `if let` guards are experimental

src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr

+66-24
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,59 @@
11
error: expected expression, found `let` statement
2-
--> $DIR/feature-gate.rs:59:16
2+
--> $DIR/feature-gate.rs:10:16
3+
|
4+
LL | () if (let 0 = 1) => {}
5+
| ^^^
6+
7+
error: expected expression, found `let` statement
8+
--> $DIR/feature-gate.rs:14:18
9+
|
10+
LL | () if (((let 0 = 1))) => {}
11+
| ^^^
12+
13+
error: expected expression, found `let` statement
14+
--> $DIR/feature-gate.rs:26:16
15+
|
16+
LL | () if (let 0 = 1) && true => {}
17+
| ^^^
18+
19+
error: expected expression, found `let` statement
20+
--> $DIR/feature-gate.rs:30:24
21+
|
22+
LL | () if true && (let 0 = 1) => {}
23+
| ^^^
24+
25+
error: expected expression, found `let` statement
26+
--> $DIR/feature-gate.rs:34:16
27+
|
28+
LL | () if (let 0 = 1) && (let 0 = 1) => {}
29+
| ^^^
30+
31+
error: expected expression, found `let` statement
32+
--> $DIR/feature-gate.rs:34:31
33+
|
34+
LL | () if (let 0 = 1) && (let 0 = 1) => {}
35+
| ^^^
36+
37+
error: expected expression, found `let` statement
38+
--> $DIR/feature-gate.rs:40:42
39+
|
40+
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
41+
| ^^^
42+
43+
error: expected expression, found `let` statement
44+
--> $DIR/feature-gate.rs:66:16
345
|
446
LL | use_expr!((let 0 = 1 && 0 == 0));
547
| ^^^
648

749
error: expected expression, found `let` statement
8-
--> $DIR/feature-gate.rs:62:16
50+
--> $DIR/feature-gate.rs:69:16
951
|
1052
LL | use_expr!((let 0 = 1));
1153
| ^^^
1254

1355
error: no rules expected the token `let`
14-
--> $DIR/feature-gate.rs:71:15
56+
--> $DIR/feature-gate.rs:78:15
1557
|
1658
LL | macro_rules! use_expr {
1759
| --------------------- when calling this macro
@@ -30,7 +72,7 @@ LL | () if let 0 = 1 => {}
3072
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
3173

3274
error[E0658]: `if let` guards are experimental
33-
--> $DIR/feature-gate.rs:16:12
75+
--> $DIR/feature-gate.rs:18:12
3476
|
3577
LL | () if true && let 0 = 1 => {}
3678
| ^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +82,7 @@ LL | () if true && let 0 = 1 => {}
4082
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
4183

4284
error[E0658]: `if let` guards are experimental
43-
--> $DIR/feature-gate.rs:20:12
85+
--> $DIR/feature-gate.rs:22:12
4486
|
4587
LL | () if let 0 = 1 && true => {}
4688
| ^^^^^^^^^^^^^^^^^^^^
@@ -50,7 +92,7 @@ LL | () if let 0 = 1 && true => {}
5092
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
5193

5294
error[E0658]: `if let` guards are experimental
53-
--> $DIR/feature-gate.rs:34:12
95+
--> $DIR/feature-gate.rs:40:12
5496
|
5597
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
5698
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +102,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
60102
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
61103

62104
error[E0658]: `if let` guards are experimental
63-
--> $DIR/feature-gate.rs:42:12
105+
--> $DIR/feature-gate.rs:49:12
64106
|
65107
LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
66108
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -70,7 +112,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
70112
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
71113

72114
error[E0658]: `if let` guards are experimental
73-
--> $DIR/feature-gate.rs:67:12
115+
--> $DIR/feature-gate.rs:74:12
74116
|
75117
LL | () if let 0 = 1 => {}
76118
| ^^^^^^^^^^^^
@@ -89,7 +131,7 @@ LL | () if (let 0 = 1) => {}
89131
= help: add `#![feature(let_chains)]` to the crate attributes to enable
90132

91133
error[E0658]: `let` expressions in this position are unstable
92-
--> $DIR/feature-gate.rs:13:18
134+
--> $DIR/feature-gate.rs:14:18
93135
|
94136
LL | () if (((let 0 = 1))) => {}
95137
| ^^^^^^^^^
@@ -98,7 +140,7 @@ LL | () if (((let 0 = 1))) => {}
98140
= help: add `#![feature(let_chains)]` to the crate attributes to enable
99141

100142
error[E0658]: `let` expressions in this position are unstable
101-
--> $DIR/feature-gate.rs:16:23
143+
--> $DIR/feature-gate.rs:18:23
102144
|
103145
LL | () if true && let 0 = 1 => {}
104146
| ^^^^^^^^^
@@ -107,7 +149,7 @@ LL | () if true && let 0 = 1 => {}
107149
= help: add `#![feature(let_chains)]` to the crate attributes to enable
108150

109151
error[E0658]: `let` expressions in this position are unstable
110-
--> $DIR/feature-gate.rs:20:15
152+
--> $DIR/feature-gate.rs:22:15
111153
|
112154
LL | () if let 0 = 1 && true => {}
113155
| ^^^^^^^^^
@@ -116,7 +158,7 @@ LL | () if let 0 = 1 && true => {}
116158
= help: add `#![feature(let_chains)]` to the crate attributes to enable
117159

118160
error[E0658]: `let` expressions in this position are unstable
119-
--> $DIR/feature-gate.rs:24:16
161+
--> $DIR/feature-gate.rs:26:16
120162
|
121163
LL | () if (let 0 = 1) && true => {}
122164
| ^^^^^^^^^
@@ -125,7 +167,7 @@ LL | () if (let 0 = 1) && true => {}
125167
= help: add `#![feature(let_chains)]` to the crate attributes to enable
126168

127169
error[E0658]: `let` expressions in this position are unstable
128-
--> $DIR/feature-gate.rs:27:24
170+
--> $DIR/feature-gate.rs:30:24
129171
|
130172
LL | () if true && (let 0 = 1) => {}
131173
| ^^^^^^^^^
@@ -134,7 +176,7 @@ LL | () if true && (let 0 = 1) => {}
134176
= help: add `#![feature(let_chains)]` to the crate attributes to enable
135177

136178
error[E0658]: `let` expressions in this position are unstable
137-
--> $DIR/feature-gate.rs:30:16
179+
--> $DIR/feature-gate.rs:34:16
138180
|
139181
LL | () if (let 0 = 1) && (let 0 = 1) => {}
140182
| ^^^^^^^^^
@@ -143,7 +185,7 @@ LL | () if (let 0 = 1) && (let 0 = 1) => {}
143185
= help: add `#![feature(let_chains)]` to the crate attributes to enable
144186

145187
error[E0658]: `let` expressions in this position are unstable
146-
--> $DIR/feature-gate.rs:30:31
188+
--> $DIR/feature-gate.rs:34:31
147189
|
148190
LL | () if (let 0 = 1) && (let 0 = 1) => {}
149191
| ^^^^^^^^^
@@ -152,7 +194,7 @@ LL | () if (let 0 = 1) && (let 0 = 1) => {}
152194
= help: add `#![feature(let_chains)]` to the crate attributes to enable
153195

154196
error[E0658]: `let` expressions in this position are unstable
155-
--> $DIR/feature-gate.rs:34:15
197+
--> $DIR/feature-gate.rs:40:15
156198
|
157199
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
158200
| ^^^^^^^^^
@@ -161,7 +203,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
161203
= help: add `#![feature(let_chains)]` to the crate attributes to enable
162204

163205
error[E0658]: `let` expressions in this position are unstable
164-
--> $DIR/feature-gate.rs:34:28
206+
--> $DIR/feature-gate.rs:40:28
165207
|
166208
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
167209
| ^^^^^^^^^
@@ -170,7 +212,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
170212
= help: add `#![feature(let_chains)]` to the crate attributes to enable
171213

172214
error[E0658]: `let` expressions in this position are unstable
173-
--> $DIR/feature-gate.rs:34:42
215+
--> $DIR/feature-gate.rs:40:42
174216
|
175217
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
176218
| ^^^^^^^^^
@@ -179,7 +221,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
179221
= help: add `#![feature(let_chains)]` to the crate attributes to enable
180222

181223
error[E0658]: `let` expressions in this position are unstable
182-
--> $DIR/feature-gate.rs:34:55
224+
--> $DIR/feature-gate.rs:40:55
183225
|
184226
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
185227
| ^^^^^^^^^
@@ -188,7 +230,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
188230
= help: add `#![feature(let_chains)]` to the crate attributes to enable
189231

190232
error[E0658]: `let` expressions in this position are unstable
191-
--> $DIR/feature-gate.rs:34:68
233+
--> $DIR/feature-gate.rs:40:68
192234
|
193235
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
194236
| ^^^^^^^^^
@@ -197,7 +239,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
197239
= help: add `#![feature(let_chains)]` to the crate attributes to enable
198240

199241
error[E0658]: `let` expressions in this position are unstable
200-
--> $DIR/feature-gate.rs:42:15
242+
--> $DIR/feature-gate.rs:49:15
201243
|
202244
LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
203245
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -206,7 +248,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
206248
= help: add `#![feature(let_chains)]` to the crate attributes to enable
207249

208250
error[E0658]: `let` expressions in this position are unstable
209-
--> $DIR/feature-gate.rs:59:16
251+
--> $DIR/feature-gate.rs:66:16
210252
|
211253
LL | use_expr!((let 0 = 1 && 0 == 0));
212254
| ^^^^^^^^^
@@ -215,14 +257,14 @@ LL | use_expr!((let 0 = 1 && 0 == 0));
215257
= help: add `#![feature(let_chains)]` to the crate attributes to enable
216258

217259
error[E0658]: `let` expressions in this position are unstable
218-
--> $DIR/feature-gate.rs:62:16
260+
--> $DIR/feature-gate.rs:69:16
219261
|
220262
LL | use_expr!((let 0 = 1));
221263
| ^^^^^^^^^
222264
|
223265
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
224266
= help: add `#![feature(let_chains)]` to the crate attributes to enable
225267

226-
error: aborting due to 25 previous errors
268+
error: aborting due to 32 previous errors
227269

228270
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)