mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 09:23:05 +00:00
Rollup merge of #98633 - c410-f3r:yet-another-let-chain, r=estebank
Fix last `let_chains` blocker In order to forbid things like `let x = (let y = 1);` or `if let a = 1 && { let x = let y = 1; } {}`, the parser **HAS** to know the context of `let`. This context thing is not a surprise in the parser because you can see **a lot** of ad hoc fixes mixing parsing logic with validation logic creating code that looks more like spaghetti with tomato sauce. To make things even greater, a new ad hoc fix was added to only allow `let`s in a valid `let_chains` context by checking the previously processed token. This was the only solution I could think of and believe me, I thought about it for a long time 👍 In the long term, it should be preferable to segregate different responsibilities or create a more robust and cleaner parser framework. cc https://github.com/rust-lang/rust/pull/94927 cc https://github.com/rust-lang/rust/issues/53667
This commit is contained in:
commit
9997c51496
@ -1393,7 +1393,9 @@ impl<'a> Parser<'a> {
|
||||
self.parse_yield_expr(attrs)
|
||||
} else if self.is_do_yeet() {
|
||||
self.parse_yeet_expr(attrs)
|
||||
} else if self.eat_keyword(kw::Let) {
|
||||
} else if self.check_keyword(kw::Let) {
|
||||
self.manage_let_chains_context();
|
||||
self.bump();
|
||||
self.parse_let_expr(attrs)
|
||||
} else if self.eat_keyword(kw::Underscore) {
|
||||
Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore, attrs))
|
||||
@ -2355,16 +2357,30 @@ impl<'a> Parser<'a> {
|
||||
Ok(cond)
|
||||
}
|
||||
|
||||
// Checks if `let` is in an invalid position like `let x = let y = 1;` or
|
||||
// if the current `let` is in a let_chains context but nested in another
|
||||
// expression like `if let Some(_) = _opt && [1, 2, 3][let _ = ()] = 1`.
|
||||
//
|
||||
// This method expects that the current token is `let`.
|
||||
fn manage_let_chains_context(&mut self) {
|
||||
debug_assert!(matches!(self.token.kind, TokenKind::Ident(kw::Let, _)));
|
||||
let is_in_a_let_chains_context_but_nested_in_other_expr = self.let_expr_allowed
|
||||
&& !matches!(
|
||||
self.prev_token.kind,
|
||||
TokenKind::AndAnd
|
||||
| TokenKind::CloseDelim(Delimiter::Brace)
|
||||
| TokenKind::Ident(kw::If, _)
|
||||
| TokenKind::Ident(kw::While, _)
|
||||
);
|
||||
if !self.let_expr_allowed || is_in_a_let_chains_context_but_nested_in_other_expr {
|
||||
self.struct_span_err(self.token.span, "expected expression, found `let` statement")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses a `let $pat = $expr` pseudo-expression.
|
||||
/// The `let` token has already been eaten.
|
||||
fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
|
||||
if !self.let_expr_allowed {
|
||||
self.struct_span_err(
|
||||
self.prev_token.span,
|
||||
"expected expression, found `let` statement",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
let lo = self.prev_token.span;
|
||||
let pat = self.parse_pat_allow_top_alt(
|
||||
None,
|
||||
|
@ -9,9 +9,11 @@ fn _if_let_guard() {
|
||||
|
||||
() if (let 0 = 1) => {}
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if (((let 0 = 1))) => {}
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if true && let 0 = 1 => {}
|
||||
//~^ ERROR `if let` guards are experimental
|
||||
@ -23,13 +25,17 @@ fn _if_let_guard() {
|
||||
|
||||
() if (let 0 = 1) && true => {}
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if true && (let 0 = 1) => {}
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if (let 0 = 1) && (let 0 = 1) => {}
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
//~^ ERROR `if let` guards are experimental
|
||||
@ -38,6 +44,7 @@ fn _if_let_guard() {
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if let Range { start: _, end: _ } = (true..true) && false => {}
|
||||
//~^ ERROR `if let` guards are experimental
|
||||
|
@ -1,17 +1,59 @@
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:59:16
|
||||
--> $DIR/feature-gate.rs:10:16
|
||||
|
|
||||
LL | () if (let 0 = 1) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:14:18
|
||||
|
|
||||
LL | () if (((let 0 = 1))) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:26:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && true => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:30:24
|
||||
|
|
||||
LL | () if true && (let 0 = 1) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:34:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:34:31
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:40:42
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:66:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1 && 0 == 0));
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:62:16
|
||||
--> $DIR/feature-gate.rs:69:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1));
|
||||
| ^^^
|
||||
|
||||
error: no rules expected the token `let`
|
||||
--> $DIR/feature-gate.rs:71:15
|
||||
--> $DIR/feature-gate.rs:78:15
|
||||
|
|
||||
LL | macro_rules! use_expr {
|
||||
| --------------------- when calling this macro
|
||||
@ -30,7 +72,7 @@ LL | () if let 0 = 1 => {}
|
||||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:16:12
|
||||
--> $DIR/feature-gate.rs:18:12
|
||||
|
|
||||
LL | () if true && let 0 = 1 => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
@ -40,7 +82,7 @@ LL | () if true && let 0 = 1 => {}
|
||||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:20:12
|
||||
--> $DIR/feature-gate.rs:22:12
|
||||
|
|
||||
LL | () if let 0 = 1 && true => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
@ -50,7 +92,7 @@ LL | () if let 0 = 1 && true => {}
|
||||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:34:12
|
||||
--> $DIR/feature-gate.rs:40:12
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -60,7 +102,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
||||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:42:12
|
||||
--> $DIR/feature-gate.rs:49:12
|
||||
|
|
||||
LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -70,7 +112,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
|
||||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:67:12
|
||||
--> $DIR/feature-gate.rs:74:12
|
||||
|
|
||||
LL | () if let 0 = 1 => {}
|
||||
| ^^^^^^^^^^^^
|
||||
@ -89,7 +131,7 @@ LL | () if (let 0 = 1) => {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:13:18
|
||||
--> $DIR/feature-gate.rs:14:18
|
||||
|
|
||||
LL | () if (((let 0 = 1))) => {}
|
||||
| ^^^^^^^^^
|
||||
@ -98,7 +140,7 @@ LL | () if (((let 0 = 1))) => {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:16:23
|
||||
--> $DIR/feature-gate.rs:18:23
|
||||
|
|
||||
LL | () if true && let 0 = 1 => {}
|
||||
| ^^^^^^^^^
|
||||
@ -107,7 +149,7 @@ LL | () if true && let 0 = 1 => {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:20:15
|
||||
--> $DIR/feature-gate.rs:22:15
|
||||
|
|
||||
LL | () if let 0 = 1 && true => {}
|
||||
| ^^^^^^^^^
|
||||
@ -116,7 +158,7 @@ LL | () if let 0 = 1 && true => {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:24:16
|
||||
--> $DIR/feature-gate.rs:26:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && true => {}
|
||||
| ^^^^^^^^^
|
||||
@ -125,7 +167,7 @@ LL | () if (let 0 = 1) && true => {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:27:24
|
||||
--> $DIR/feature-gate.rs:30:24
|
||||
|
|
||||
LL | () if true && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
@ -134,7 +176,7 @@ LL | () if true && (let 0 = 1) => {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:30:16
|
||||
--> $DIR/feature-gate.rs:34:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
@ -143,7 +185,7 @@ LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:30:31
|
||||
--> $DIR/feature-gate.rs:34:31
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
@ -152,7 +194,7 @@ LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:15
|
||||
--> $DIR/feature-gate.rs:40:15
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
@ -161,7 +203,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:28
|
||||
--> $DIR/feature-gate.rs:40:28
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
@ -170,7 +212,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:42
|
||||
--> $DIR/feature-gate.rs:40:42
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
@ -179,7 +221,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:55
|
||||
--> $DIR/feature-gate.rs:40:55
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
@ -188,7 +230,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:68
|
||||
--> $DIR/feature-gate.rs:40:68
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
@ -197,7 +239,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:42:15
|
||||
--> $DIR/feature-gate.rs:49:15
|
||||
|
|
||||
LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -206,7 +248,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:59:16
|
||||
--> $DIR/feature-gate.rs:66:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1 && 0 == 0));
|
||||
| ^^^^^^^^^
|
||||
@ -215,7 +257,7 @@ LL | use_expr!((let 0 = 1 && 0 == 0));
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:62:16
|
||||
--> $DIR/feature-gate.rs:69:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1));
|
||||
| ^^^^^^^^^
|
||||
@ -223,6 +265,6 @@ LL | use_expr!((let 0 = 1));
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 25 previous errors
|
||||
error: aborting due to 32 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -28,47 +28,61 @@ fn main() {}
|
||||
fn _if() {
|
||||
if (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if (((let 0 = 1))) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if (let 0 = 1) && true {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if true && (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if (let 0 = 1) && (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
fn _while() {
|
||||
while (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while (((let 0 = 1))) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while (let 0 = 1) && true {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while true && (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while (let 0 = 1) && (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
fn _macros() {
|
||||
@ -89,39 +103,64 @@ fn _macros() {
|
||||
}
|
||||
|
||||
fn nested_within_if_expr() {
|
||||
if &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
if &let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if !let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
if *let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR type `bool` cannot be dereferenced
|
||||
if -let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR cannot apply unary operator `-` to type `bool`
|
||||
if !let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if *let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR type `bool` cannot be dereferenced
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if -let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR cannot apply unary operator `-` to type `bool`
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
fn _check_try_binds_tighter() -> Result<(), ()> {
|
||||
if let 0 = 0? {}
|
||||
//~^ ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
Ok(())
|
||||
}
|
||||
if (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
if (let 0 = 0)? {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
//~| ERROR the `?` operator can only be used in a function that returns `Result`
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
if (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
if true && (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
if true || (true && let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
if true || let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if (true || let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if true && (true || let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if true || (true && let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
|
||||
let mut x = true;
|
||||
if x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
if x = let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if true..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
if ..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
if (let 0 = 0).. {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
if true..(let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if ..(let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if (let 0 = 0).. {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
// Binds as `(let ... = true)..true &&/|| false`.
|
||||
if let Range { start: _, end: _ } = true..true && false {}
|
||||
@ -151,42 +190,68 @@ fn nested_within_if_expr() {
|
||||
|
||||
if let true = let true = true {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
fn nested_within_while_expr() {
|
||||
while &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
while &let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while !let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
while *let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR type `bool` cannot be dereferenced
|
||||
while -let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR cannot apply unary operator `-` to type `bool`
|
||||
while !let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while *let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR type `bool` cannot be dereferenced
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while -let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR cannot apply unary operator `-` to type `bool`
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
fn _check_try_binds_tighter() -> Result<(), ()> {
|
||||
while let 0 = 0? {}
|
||||
//~^ ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
Ok(())
|
||||
}
|
||||
while (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
while (let 0 = 0)? {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
//~| ERROR the `?` operator can only be used in a function that returns `Result`
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
while (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
while true && (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
while true || (true && let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
while true || let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while (true || let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while true && (true || let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while true || (true && let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
|
||||
let mut x = true;
|
||||
while x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
while x = let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while true..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
while ..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
while (let 0 = 0).. {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
while true..(let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while ..(let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while (let 0 = 0).. {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
// Binds as `(let ... = true)..true &&/|| false`.
|
||||
while let Range { start: _, end: _ } = true..true && false {}
|
||||
@ -216,6 +281,7 @@ fn nested_within_while_expr() {
|
||||
|
||||
while let true = let true = true {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
fn not_error_because_clarified_intent() {
|
||||
@ -316,15 +382,18 @@ fn inside_const_generic_arguments() {
|
||||
impl<const B: bool> A<{B}> { const O: u32 = 5; }
|
||||
|
||||
if let A::<{
|
||||
true && let 1 = 1 //~ ERROR `let` expressions are not supported here
|
||||
true && let 1 = 1
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
}>::O = 5 {}
|
||||
|
||||
while let A::<{
|
||||
true && let 1 = 1 //~ ERROR `let` expressions are not supported here
|
||||
true && let 1 = 1
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
}>::O = 5 {}
|
||||
|
||||
if A::<{
|
||||
true && let 1 = 1 //~ ERROR `let` expressions are not supported here
|
||||
true && let 1 = 1
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
}>::O == 5 {}
|
||||
|
||||
// In the cases above we have `ExprKind::Block` to help us out.
|
||||
@ -345,14 +414,18 @@ fn with_parenthesis() {
|
||||
|
||||
if (let Some(a) = opt && true) {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
if (let Some(a) = opt) && true {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
if (let Some(a) = opt) && (let Some(b) = a) {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
if let Some(a) = opt && (true && true) {
|
||||
}
|
||||
@ -360,13 +433,18 @@ fn with_parenthesis() {
|
||||
if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
if (let Some(a) = opt && (let Some(b) = a)) && true {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
if (let Some(a) = opt && (true)) && true {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
if (true && (true)) && let Some(a) = opt {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,11 @@ fn _if() {
|
||||
|
||||
if let Range { start: _, end: _ } = (true..true) && false {}
|
||||
//~^ ERROR `let` expressions in this position are unstable [E0658]
|
||||
|
||||
if let 1 = 1 && let true = { true } && false {
|
||||
//~^ ERROR `let` expressions in this position are unstable [E0658]
|
||||
//~| ERROR `let` expressions in this position are unstable [E0658]
|
||||
}
|
||||
}
|
||||
|
||||
fn _while() {
|
||||
|
@ -1,17 +1,17 @@
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:50:20
|
||||
--> $DIR/feature-gate.rs:55:20
|
||||
|
|
||||
LL | #[cfg(FALSE)] (let 0 = 1);
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:40:17
|
||||
--> $DIR/feature-gate.rs:45:17
|
||||
|
|
||||
LL | noop_expr!((let 0 = 1));
|
||||
| ^^^
|
||||
|
||||
error: no rules expected the token `let`
|
||||
--> $DIR/feature-gate.rs:53:15
|
||||
--> $DIR/feature-gate.rs:58:15
|
||||
|
|
||||
LL | macro_rules! use_expr {
|
||||
| --------------------- when calling this macro
|
||||
@ -47,7 +47,25 @@ LL | if let Range { start: _, end: _ } = (true..true) && false {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:27:19
|
||||
--> $DIR/feature-gate.rs:23:8
|
||||
|
|
||||
LL | if let 1 = 1 && let true = { true } && false {
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:23:21
|
||||
|
|
||||
LL | if let 1 = 1 && let true = { true } && false {
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:32:19
|
||||
|
|
||||
LL | while true && let 0 = 1 {}
|
||||
| ^^^^^^^^^
|
||||
@ -56,7 +74,7 @@ LL | while true && let 0 = 1 {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:30:11
|
||||
--> $DIR/feature-gate.rs:35:11
|
||||
|
|
||||
LL | while let 0 = 1 && true {}
|
||||
| ^^^^^^^^^
|
||||
@ -65,7 +83,7 @@ LL | while let 0 = 1 && true {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:33:11
|
||||
--> $DIR/feature-gate.rs:38:11
|
||||
|
|
||||
LL | while let Range { start: _, end: _ } = (true..true) && false {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -74,7 +92,7 @@ LL | while let Range { start: _, end: _ } = (true..true) && false {}
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:50:20
|
||||
--> $DIR/feature-gate.rs:55:20
|
||||
|
|
||||
LL | #[cfg(FALSE)] (let 0 = 1);
|
||||
| ^^^^^^^^^
|
||||
@ -83,7 +101,7 @@ LL | #[cfg(FALSE)] (let 0 = 1);
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:40:17
|
||||
--> $DIR/feature-gate.rs:45:17
|
||||
|
|
||||
LL | noop_expr!((let 0 = 1));
|
||||
| ^^^^^^^^^
|
||||
@ -91,6 +109,6 @@ LL | noop_expr!((let 0 = 1));
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -1,17 +1,45 @@
|
||||
// check-pass
|
||||
// known-bug
|
||||
|
||||
#![feature(let_chains)]
|
||||
|
||||
fn main() {
|
||||
let _opt = Some(1i32);
|
||||
|
||||
#[cfg(FALSE)]
|
||||
{
|
||||
let _ = &&let Some(x) = Some(42);
|
||||
//~^ ERROR expected expression, found `let` statement
|
||||
}
|
||||
#[cfg(FALSE)]
|
||||
{
|
||||
if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 {
|
||||
//~^ ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
{
|
||||
if let Some(elem) = _opt && {
|
||||
[1, 2, 3][let _ = ()];
|
||||
//~^ ERROR expected expression, found `let` statement
|
||||
true
|
||||
} {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
{
|
||||
if let Some(elem) = _opt && [1, 2, 3][let _ = ()] = 1 {
|
||||
//~^ ERROR expected expression, found `let` statement
|
||||
true
|
||||
}
|
||||
}
|
||||
#[cfg(FALSE)]
|
||||
{
|
||||
if let a = 1 && {
|
||||
let x = let y = 1;
|
||||
//~^ ERROR expected expression, found `let` statement
|
||||
} {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:8:19
|
||||
|
|
||||
LL | let _ = &&let Some(x) = Some(42);
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:13:47
|
||||
|
|
||||
LL | if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 {
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:13:57
|
||||
|
|
||||
LL | if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 {
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:23:23
|
||||
|
|
||||
LL | [1, 2, 3][let _ = ()];
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:32:47
|
||||
|
|
||||
LL | if let Some(elem) = _opt && [1, 2, 3][let _ = ()] = 1 {
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:40:21
|
||||
|
|
||||
LL | let x = let y = 1;
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user