summaryrefslogtreecommitdiffstats
path: root/tests/ui/rfc-2497-if-let-chains
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
commit64d98f8ee037282c35007b64c2649055c56af1db (patch)
tree5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/rfc-2497-if-let-chains
parentAdding debian version 1.67.1+dfsg1-1. (diff)
downloadrustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz
rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/rfc-2497-if-let-chains')
-rw-r--r--tests/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs16
-rw-r--r--tests/ui/rfc-2497-if-let-chains/ast-pretty-check.rs6
-rw-r--r--tests/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout10
-rw-r--r--tests/ui/rfc-2497-if-let-chains/chains-without-let.rs20
-rw-r--r--tests/ui/rfc-2497-if-let-chains/chains-without-let.stderr33
-rw-r--r--tests/ui/rfc-2497-if-let-chains/disallowed-positions.rs480
-rw-r--r--tests/ui/rfc-2497-if-let-chains/disallowed-positions.stderr1911
-rw-r--r--tests/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs55
-rw-r--r--tests/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr142
-rw-r--r--tests/ui/rfc-2497-if-let-chains/feature-gate.rs62
-rw-r--r--tests/ui/rfc-2497-if-let-chains/feature-gate.stderr120
-rw-r--r--tests/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs45
-rw-r--r--tests/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr38
-rw-r--r--tests/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr115
-rw-r--r--tests/ui/rfc-2497-if-let-chains/irrefutable-lets.rs78
-rw-r--r--tests/ui/rfc-2497-if-let-chains/issue-88498.rs16
-rw-r--r--tests/ui/rfc-2497-if-let-chains/issue-90722.rs11
-rw-r--r--tests/ui/rfc-2497-if-let-chains/issue-92145.rs11
-rw-r--r--tests/ui/rfc-2497-if-let-chains/issue-93150.rs8
-rw-r--r--tests/ui/rfc-2497-if-let-chains/issue-93150.stderr22
-rw-r--r--tests/ui/rfc-2497-if-let-chains/issue-99938.rs31
-rw-r--r--tests/ui/rfc-2497-if-let-chains/no-double-assigments.rs9
-rw-r--r--tests/ui/rfc-2497-if-let-chains/protect-precedences.rs17
-rw-r--r--tests/ui/rfc-2497-if-let-chains/protect-precedences.stderr12
-rw-r--r--tests/ui/rfc-2497-if-let-chains/then-else-blocks.rs49
25 files changed, 3317 insertions, 0 deletions
diff --git a/tests/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs b/tests/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs
new file mode 100644
index 000000000..d851fac8e
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs
@@ -0,0 +1,16 @@
+// run-pass
+
+#![feature(let_chains)]
+#![allow(irrefutable_let_patterns)]
+
+fn main() {
+ let first = Some(1);
+ let second = Some(2);
+ let mut n = 0;
+ if let x = first && let y = second && 1 == 1 {
+ assert_eq!(x, first);
+ assert_eq!(y, second);
+ n = 1;
+ }
+ assert_eq!(n, 1);
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/ast-pretty-check.rs b/tests/ui/rfc-2497-if-let-chains/ast-pretty-check.rs
new file mode 100644
index 000000000..69bc189dd
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/ast-pretty-check.rs
@@ -0,0 +1,6 @@
+// check-pass
+// compile-flags: -Z unpretty=expanded
+
+fn main() {
+ if let 0 = 1 {}
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout b/tests/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout
new file mode 100644
index 000000000..e737ef26e
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout
@@ -0,0 +1,10 @@
+#![feature(prelude_import)]
+#![no_std]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+// check-pass
+// compile-flags: -Z unpretty=expanded
+
+fn main() { if let 0 = 1 {} }
diff --git a/tests/ui/rfc-2497-if-let-chains/chains-without-let.rs b/tests/ui/rfc-2497-if-let-chains/chains-without-let.rs
new file mode 100644
index 000000000..e0dded152
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/chains-without-let.rs
@@ -0,0 +1,20 @@
+fn and_chain() {
+ let z;
+ if true && { z = 3; true} && z == 3 {}
+ //~^ ERROR E0381
+}
+
+fn and_chain_2() {
+ let z;
+ true && { z = 3; true} && z == 3;
+ //~^ ERROR E0381
+}
+
+fn or_chain() {
+ let z;
+ if false || { z = 3; false} || z == 3 {}
+ //~^ ERROR E0381
+}
+
+fn main() {
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/chains-without-let.stderr b/tests/ui/rfc-2497-if-let-chains/chains-without-let.stderr
new file mode 100644
index 000000000..30d5a6779
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/chains-without-let.stderr
@@ -0,0 +1,33 @@
+error[E0381]: used binding `z` is possibly-uninitialized
+ --> $DIR/chains-without-let.rs:3:34
+ |
+LL | let z;
+ | - binding declared here but left uninitialized
+LL | if true && { z = 3; true} && z == 3 {}
+ | ----- ^ `z` used here but it is possibly-uninitialized
+ | |
+ | binding initialized here in some conditions
+
+error[E0381]: used binding `z` is possibly-uninitialized
+ --> $DIR/chains-without-let.rs:9:31
+ |
+LL | let z;
+ | - binding declared here but left uninitialized
+LL | true && { z = 3; true} && z == 3;
+ | ----- ^ `z` used here but it is possibly-uninitialized
+ | |
+ | binding initialized here in some conditions
+
+error[E0381]: used binding `z` is possibly-uninitialized
+ --> $DIR/chains-without-let.rs:15:36
+ |
+LL | let z;
+ | - binding declared here but left uninitialized
+LL | if false || { z = 3; false} || z == 3 {}
+ | ----- ^ `z` used here but it is possibly-uninitialized
+ | |
+ | binding initialized here in some conditions
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/tests/ui/rfc-2497-if-let-chains/disallowed-positions.rs b/tests/ui/rfc-2497-if-let-chains/disallowed-positions.rs
new file mode 100644
index 000000000..2a9a5472b
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/disallowed-positions.rs
@@ -0,0 +1,480 @@
+// Here we test that `lowering` behaves correctly wrt. `let $pats = $expr` expressions.
+//
+// We want to make sure that `let` is banned in situations other than:
+//
+// expr =
+// | ...
+// | "if" expr_with_let block {"else" block}?
+// | {label ":"}? while" expr_with_let block
+// ;
+//
+// expr_with_let =
+// | "let" top_pats "=" expr
+// | expr_with_let "&&" expr_with_let
+// | "(" expr_with_let ")"
+// | expr
+// ;
+//
+// To that end, we check some positions which is not part of the language above.
+
+#![feature(let_chains)] // Avoid inflating `.stderr` with overzealous gates in this test.
+
+#![allow(irrefutable_let_patterns)]
+
+use std::ops::Range;
+
+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
+ //~| ERROR expected expression, found `let` statement
+ //~| 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
+ //~| ERROR expected expression, found `let` statement
+ //~| ERROR expected expression, found `let` statement
+}
+
+fn _macros() {
+ macro_rules! use_expr {
+ ($e:expr) => {
+ if $e {}
+ while $e {}
+ }
+ }
+ use_expr!((let 0 = 1 && 0 == 0));
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ use_expr!((let 0 = 1));
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+}
+
+fn nested_within_if_expr() {
+ 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 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`
+ //~| 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
+ //~| 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
+ //~| ERROR expected expression, found `let` statement
+
+ let mut x = true;
+ 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
+ //~| 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 {}
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+ if let Range { start: _, end: _ } = true..true || false {}
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+
+ // Binds as `(let Range { start: F, end } = F)..(|| true)`.
+ const F: fn() -> bool = || true;
+ if let Range { start: F, end } = F..|| true {}
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+
+ // Binds as `(let Range { start: true, end } = t)..(&&false)`.
+ let t = &&true;
+ if let Range { start: true, end } = t..&&false {}
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+
+ 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
+ //~| ERROR expected expression, found `let` statement
+
+ 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`
+ //~| 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
+ //~| 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
+ //~| ERROR expected expression, found `let` statement
+
+ let mut x = true;
+ 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
+ //~| 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 {}
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+ while let Range { start: _, end: _ } = true..true || false {}
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+
+ // Binds as `(let Range { start: F, end } = F)..(|| true)`.
+ const F: fn() -> bool = || true;
+ while let Range { start: F, end } = F..|| true {}
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+
+ // Binds as `(let Range { start: true, end } = t)..(&&false)`.
+ let t = &&true;
+ while let Range { start: true, end } = t..&&false {}
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+
+ 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() {
+ if let Range { start: _, end: _ } = (true..true || false) { }
+
+ if let Range { start: _, end: _ } = (true..true && false) { }
+
+ while let Range { start: _, end: _ } = (true..true || false) { }
+
+ while let Range { start: _, end: _ } = (true..true && false) { }
+}
+
+fn outside_if_and_while_expr() {
+ &let 0 = 0;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+
+ !let 0 = 0;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ *let 0 = 0;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR type `bool` cannot be dereferenced
+ //~| ERROR expected expression, found `let` statement
+ -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<(), ()> {
+ let 0 = 0?;
+ //~^ ERROR the `?` operator can only be applied to values that implement `Try`
+ Ok(())
+ }
+ (let 0 = 0)?;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR the `?` operator can only be used in a function that returns `Result`
+ //~| ERROR the `?` operator can only be applied to values that implement `Try`
+ //~| ERROR expected expression, found `let` statement
+
+ true || let 0 = 0;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ (true || let 0 = 0);
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ true && (true || let 0 = 0);
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+
+ let mut x = true;
+ x = let 0 = 0;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+
+ true..(let 0 = 0);
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ ..(let 0 = 0);
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ (let 0 = 0)..;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+
+ (let Range { start: _, end: _ } = true..true || false);
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR mismatched types
+ //~| ERROR expected expression, found `let` statement
+
+ (let true = let true = true);
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ //~| ERROR expected expression, found `let` statement
+
+ {
+ #[cfg(FALSE)]
+ let x = true && let y = 1;
+ //~^ ERROR expected expression, found `let` statement
+ }
+
+ #[cfg(FALSE)]
+ {
+ [1, 2, 3][let _ = ()]
+ //~^ ERROR expected expression, found `let` statement
+ }
+
+ // Check function tail position.
+ &let 0 = 0
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR mismatched types
+ //~| ERROR expected expression, found `let` statement
+}
+
+// Let's make sure that `let` inside const generic arguments are considered.
+fn inside_const_generic_arguments() {
+ struct A<const B: bool>;
+ impl<const B: bool> A<{B}> { const O: u32 = 5; }
+
+ if let A::<{
+ true && let 1 = 1
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ }>::O = 5 {}
+
+ while let A::<{
+ true && let 1 = 1
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ }>::O = 5 {}
+
+ if A::<{
+ true && let 1 = 1
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ }>::O == 5 {}
+
+ // In the cases above we have `ExprKind::Block` to help us out.
+ // Below however, we would not have a block and so an implementation might go
+ // from visiting expressions to types without banning `let` expressions down the tree.
+ // This tests ensures that we are not caught by surprise should the parser
+ // admit non-IDENT expressions in const generic arguments.
+
+ if A::<
+ true && let 1 = 1
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expressions must be enclosed in braces
+ //~| ERROR expected expression, found `let` statement
+ >::O == 5 {}
+}
+
+fn with_parenthesis() {
+ let opt = Some(Some(1i32));
+
+ 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) {
+ }
+
+ 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 {
+ }
+ if (true) && let Some(a) = opt {
+ }
+ if true && let Some(a) = opt {
+ }
+
+ let fun = || true;
+ if let true = (true && fun()) && (true) {
+ }
+
+ #[cfg(FALSE)]
+ let x = (true && let y = 1);
+ //~^ ERROR expected expression, found `let` statement
+
+ #[cfg(FALSE)]
+ {
+ ([1, 2, 3][let _ = ()])
+ //~^ ERROR expected expression, found `let` statement
+ }
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/tests/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
new file mode 100644
index 000000000..3028f8dbd
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -0,0 +1,1911 @@
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:29:9
+ |
+LL | if (let 0 = 1) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:33:11
+ |
+LL | if (((let 0 = 1))) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:37:9
+ |
+LL | if (let 0 = 1) && true {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:41:17
+ |
+LL | if true && (let 0 = 1) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:45:9
+ |
+LL | if (let 0 = 1) && (let 0 = 1) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:45:24
+ |
+LL | if (let 0 = 1) && (let 0 = 1) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:51:35
+ |
+LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:51:48
+ |
+LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:51:61
+ |
+LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:61:12
+ |
+LL | while (let 0 = 1) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:65:14
+ |
+LL | while (((let 0 = 1))) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:69:12
+ |
+LL | while (let 0 = 1) && true {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:73:20
+ |
+LL | while true && (let 0 = 1) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:77:12
+ |
+LL | while (let 0 = 1) && (let 0 = 1) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:77:27
+ |
+LL | while (let 0 = 1) && (let 0 = 1) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:83:38
+ |
+LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:83:51
+ |
+LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:83:64
+ |
+LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:110:9
+ |
+LL | if &let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:115:9
+ |
+LL | if !let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:118:9
+ |
+LL | if *let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:122:9
+ |
+LL | if -let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:132:9
+ |
+LL | if (let 0 = 0)? {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:138:16
+ |
+LL | if true || let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:141:17
+ |
+LL | if (true || let 0 = 0) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:144:25
+ |
+LL | if true && (true || let 0 = 0) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:147:25
+ |
+LL | if true || (true && let 0 = 0) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:152:12
+ |
+LL | if x = let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:157:15
+ |
+LL | if true..(let 0 = 0) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:161:11
+ |
+LL | if ..(let 0 = 0) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:165:9
+ |
+LL | if (let 0 = 0).. {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:196:19
+ |
+LL | if let true = let true = true {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:202:12
+ |
+LL | while &let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:207:12
+ |
+LL | while !let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:210:12
+ |
+LL | while *let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:214:12
+ |
+LL | while -let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:224:12
+ |
+LL | while (let 0 = 0)? {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:230:19
+ |
+LL | while true || let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:233:20
+ |
+LL | while (true || let 0 = 0) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:236:28
+ |
+LL | while true && (true || let 0 = 0) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:239:28
+ |
+LL | while true || (true && let 0 = 0) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:244:15
+ |
+LL | while x = let 0 = 0 {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:249:18
+ |
+LL | while true..(let 0 = 0) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:253:14
+ |
+LL | while ..(let 0 = 0) {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:257:12
+ |
+LL | while (let 0 = 0).. {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:288:22
+ |
+LL | while let true = let true = true {}
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:304:6
+ |
+LL | &let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:308:6
+ |
+LL | !let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:311:6
+ |
+LL | *let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:315:6
+ |
+LL | -let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:325:6
+ |
+LL | (let 0 = 0)?;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:331:13
+ |
+LL | true || let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:334:14
+ |
+LL | (true || let 0 = 0);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:337:22
+ |
+LL | true && (true || let 0 = 0);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:342:9
+ |
+LL | x = let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:346:12
+ |
+LL | true..(let 0 = 0);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:349:8
+ |
+LL | ..(let 0 = 0);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:352:6
+ |
+LL | (let 0 = 0)..;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:356:6
+ |
+LL | (let Range { start: _, end: _ } = true..true || false);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:361:6
+ |
+LL | (let true = let true = true);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:361:17
+ |
+LL | (let true = let true = true);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:368:25
+ |
+LL | let x = true && let y = 1;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:374:19
+ |
+LL | [1, 2, 3][let _ = ()]
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:379:6
+ |
+LL | &let 0 = 0
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:391:17
+ |
+LL | true && let 1 = 1
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:397:17
+ |
+LL | true && let 1 = 1
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:403:17
+ |
+LL | true && let 1 = 1
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:415:17
+ |
+LL | true && let 1 = 1
+ | ^^^
+
+error: expressions must be enclosed in braces to be used as const generic arguments
+ --> $DIR/disallowed-positions.rs:415:9
+ |
+LL | true && let 1 = 1
+ | ^^^^^^^^^^^^^^^^^
+ |
+help: enclose the `const` expression in braces
+ |
+LL | { true && let 1 = 1 }
+ | + +
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:425:9
+ |
+LL | if (let Some(a) = opt && true) {
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:430:9
+ |
+LL | if (let Some(a) = opt) && true {
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:434:9
+ |
+LL | if (let Some(a) = opt) && (let Some(b) = a) {
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:434:32
+ |
+LL | if (let Some(a) = opt) && (let Some(b) = a) {
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:443:9
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:443:31
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:449:9
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && true {
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:449:31
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && true {
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:455:9
+ |
+LL | if (let Some(a) = opt && (true)) && true {
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:472:22
+ |
+LL | let x = (true && let y = 1);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:477:20
+ |
+LL | ([1, 2, 3][let _ = ()])
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:99:16
+ |
+LL | use_expr!((let 0 = 1 && 0 == 0));
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:103:16
+ |
+LL | use_expr!((let 0 = 1));
+ | ^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:29:9
+ |
+LL | if (let 0 = 1) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:29:9
+ |
+LL | if (let 0 = 1) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:33:11
+ |
+LL | if (((let 0 = 1))) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:33:11
+ |
+LL | if (((let 0 = 1))) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:37:9
+ |
+LL | if (let 0 = 1) && true {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:37:9
+ |
+LL | if (let 0 = 1) && true {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:41:17
+ |
+LL | if true && (let 0 = 1) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:41:17
+ |
+LL | if true && (let 0 = 1) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:45:9
+ |
+LL | if (let 0 = 1) && (let 0 = 1) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:45:9
+ |
+LL | if (let 0 = 1) && (let 0 = 1) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:45:24
+ |
+LL | if (let 0 = 1) && (let 0 = 1) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:45:24
+ |
+LL | if (let 0 = 1) && (let 0 = 1) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:51:35
+ |
+LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:51:35
+ |
+LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:51:48
+ |
+LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:51:35
+ |
+LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:51:61
+ |
+LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:51:35
+ |
+LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:61:12
+ |
+LL | while (let 0 = 1) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:61:12
+ |
+LL | while (let 0 = 1) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:65:14
+ |
+LL | while (((let 0 = 1))) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:65:14
+ |
+LL | while (((let 0 = 1))) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:69:12
+ |
+LL | while (let 0 = 1) && true {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:69:12
+ |
+LL | while (let 0 = 1) && true {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:73:20
+ |
+LL | while true && (let 0 = 1) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:73:20
+ |
+LL | while true && (let 0 = 1) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:77:12
+ |
+LL | while (let 0 = 1) && (let 0 = 1) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:77:12
+ |
+LL | while (let 0 = 1) && (let 0 = 1) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:77:27
+ |
+LL | while (let 0 = 1) && (let 0 = 1) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:77:27
+ |
+LL | while (let 0 = 1) && (let 0 = 1) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:83:38
+ |
+LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:83:38
+ |
+LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:83:51
+ |
+LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:83:38
+ |
+LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:83:64
+ |
+LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:83:38
+ |
+LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:99:16
+ |
+LL | use_expr!((let 0 = 1 && 0 == 0));
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:99:16
+ |
+LL | use_expr!((let 0 = 1 && 0 == 0));
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:99:16
+ |
+LL | use_expr!((let 0 = 1 && 0 == 0));
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:99:16
+ |
+LL | use_expr!((let 0 = 1 && 0 == 0));
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:103:16
+ |
+LL | use_expr!((let 0 = 1));
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:103:16
+ |
+LL | use_expr!((let 0 = 1));
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:103:16
+ |
+LL | use_expr!((let 0 = 1));
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:103:16
+ |
+LL | use_expr!((let 0 = 1));
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:110:9
+ |
+LL | if &let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:115:9
+ |
+LL | if !let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:118:9
+ |
+LL | if *let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:122:9
+ |
+LL | if -let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:132:9
+ |
+LL | if (let 0 = 0)? {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:132:9
+ |
+LL | if (let 0 = 0)? {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:138:16
+ |
+LL | if true || let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `||` operators are not supported in let chain expressions
+ --> $DIR/disallowed-positions.rs:138:13
+ |
+LL | if true || let 0 = 0 {}
+ | ^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:141:17
+ |
+LL | if (true || let 0 = 0) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `||` operators are not supported in let chain expressions
+ --> $DIR/disallowed-positions.rs:141:14
+ |
+LL | if (true || let 0 = 0) {}
+ | ^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:144:25
+ |
+LL | if true && (true || let 0 = 0) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `||` operators are not supported in let chain expressions
+ --> $DIR/disallowed-positions.rs:144:22
+ |
+LL | if true && (true || let 0 = 0) {}
+ | ^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:147:25
+ |
+LL | if true || (true && let 0 = 0) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:147:17
+ |
+LL | if true || (true && let 0 = 0) {}
+ | ^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:152:12
+ |
+LL | if x = let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:157:15
+ |
+LL | if true..(let 0 = 0) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:157:15
+ |
+LL | if true..(let 0 = 0) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:161:11
+ |
+LL | if ..(let 0 = 0) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:161:11
+ |
+LL | if ..(let 0 = 0) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:165:9
+ |
+LL | if (let 0 = 0).. {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:165:9
+ |
+LL | if (let 0 = 0).. {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:171:8
+ |
+LL | if let Range { start: _, end: _ } = true..true && false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:175:8
+ |
+LL | if let Range { start: _, end: _ } = true..true || false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:182:8
+ |
+LL | if let Range { start: F, end } = F..|| true {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:190:8
+ |
+LL | if let Range { start: true, end } = t..&&false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:196:19
+ |
+LL | if let true = let true = true {}
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:202:12
+ |
+LL | while &let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:207:12
+ |
+LL | while !let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:210:12
+ |
+LL | while *let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:214:12
+ |
+LL | while -let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:224:12
+ |
+LL | while (let 0 = 0)? {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:224:12
+ |
+LL | while (let 0 = 0)? {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:230:19
+ |
+LL | while true || let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `||` operators are not supported in let chain expressions
+ --> $DIR/disallowed-positions.rs:230:16
+ |
+LL | while true || let 0 = 0 {}
+ | ^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:233:20
+ |
+LL | while (true || let 0 = 0) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `||` operators are not supported in let chain expressions
+ --> $DIR/disallowed-positions.rs:233:17
+ |
+LL | while (true || let 0 = 0) {}
+ | ^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:236:28
+ |
+LL | while true && (true || let 0 = 0) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `||` operators are not supported in let chain expressions
+ --> $DIR/disallowed-positions.rs:236:25
+ |
+LL | while true && (true || let 0 = 0) {}
+ | ^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:239:28
+ |
+LL | while true || (true && let 0 = 0) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:239:20
+ |
+LL | while true || (true && let 0 = 0) {}
+ | ^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:244:15
+ |
+LL | while x = let 0 = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:249:18
+ |
+LL | while true..(let 0 = 0) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:249:18
+ |
+LL | while true..(let 0 = 0) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:253:14
+ |
+LL | while ..(let 0 = 0) {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:253:14
+ |
+LL | while ..(let 0 = 0) {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:257:12
+ |
+LL | while (let 0 = 0).. {}
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:257:12
+ |
+LL | while (let 0 = 0).. {}
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:263:11
+ |
+LL | while let Range { start: _, end: _ } = true..true && false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:267:11
+ |
+LL | while let Range { start: _, end: _ } = true..true || false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:274:11
+ |
+LL | while let Range { start: F, end } = F..|| true {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:282:11
+ |
+LL | while let Range { start: true, end } = t..&&false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:288:22
+ |
+LL | while let true = let true = true {}
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:304:6
+ |
+LL | &let 0 = 0;
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:308:6
+ |
+LL | !let 0 = 0;
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:311:6
+ |
+LL | *let 0 = 0;
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:315:6
+ |
+LL | -let 0 = 0;
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:325:6
+ |
+LL | (let 0 = 0)?;
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:325:6
+ |
+LL | (let 0 = 0)?;
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:331:13
+ |
+LL | true || let 0 = 0;
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `||` operators are not supported in let chain expressions
+ --> $DIR/disallowed-positions.rs:331:10
+ |
+LL | true || let 0 = 0;
+ | ^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:334:14
+ |
+LL | (true || let 0 = 0);
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `||` operators are not supported in let chain expressions
+ --> $DIR/disallowed-positions.rs:334:11
+ |
+LL | (true || let 0 = 0);
+ | ^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:337:22
+ |
+LL | true && (true || let 0 = 0);
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `||` operators are not supported in let chain expressions
+ --> $DIR/disallowed-positions.rs:337:19
+ |
+LL | true && (true || let 0 = 0);
+ | ^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:342:9
+ |
+LL | x = let 0 = 0;
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:346:12
+ |
+LL | true..(let 0 = 0);
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:346:12
+ |
+LL | true..(let 0 = 0);
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:349:8
+ |
+LL | ..(let 0 = 0);
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:349:8
+ |
+LL | ..(let 0 = 0);
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:352:6
+ |
+LL | (let 0 = 0)..;
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:352:6
+ |
+LL | (let 0 = 0)..;
+ | ^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:356:6
+ |
+LL | (let Range { start: _, end: _ } = true..true || false);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:361:6
+ |
+LL | (let true = let true = true);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:361:6
+ |
+LL | (let true = let true = true);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:379:6
+ |
+LL | &let 0 = 0
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:391:17
+ |
+LL | true && let 1 = 1
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:397:17
+ |
+LL | true && let 1 = 1
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:403:17
+ |
+LL | true && let 1 = 1
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:415:17
+ |
+LL | true && let 1 = 1
+ | ^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:425:9
+ |
+LL | if (let Some(a) = opt && true) {
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:425:9
+ |
+LL | if (let Some(a) = opt && true) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:430:9
+ |
+LL | if (let Some(a) = opt) && true {
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:430:9
+ |
+LL | if (let Some(a) = opt) && true {
+ | ^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:434:9
+ |
+LL | if (let Some(a) = opt) && (let Some(b) = a) {
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:434:9
+ |
+LL | if (let Some(a) = opt) && (let Some(b) = a) {
+ | ^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:434:32
+ |
+LL | if (let Some(a) = opt) && (let Some(b) = a) {
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:434:32
+ |
+LL | if (let Some(a) = opt) && (let Some(b) = a) {
+ | ^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:443:9
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:443:9
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:443:31
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:443:31
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
+ | ^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:449:9
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && true {
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:449:9
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && true {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:449:31
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && true {
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:449:31
+ |
+LL | if (let Some(a) = opt && (let Some(b) = a)) && true {
+ | ^^^^^^^^^^^^^^^
+
+error: `let` expressions are not supported here
+ --> $DIR/disallowed-positions.rs:455:9
+ |
+LL | if (let Some(a) = opt && (true)) && true {
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+ --> $DIR/disallowed-positions.rs:455:9
+ |
+LL | if (let Some(a) = opt && (true)) && true {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:110:8
+ |
+LL | if &let 0 = 0 {}
+ | ^^^^^^^^^^ expected `bool`, found `&bool`
+ |
+help: consider removing the borrow
+ |
+LL - if &let 0 = 0 {}
+LL + if let 0 = 0 {}
+ |
+
+error[E0614]: type `bool` cannot be dereferenced
+ --> $DIR/disallowed-positions.rs:118:8
+ |
+LL | if *let 0 = 0 {}
+ | ^^^^^^^^^^
+
+error[E0600]: cannot apply unary operator `-` to type `bool`
+ --> $DIR/disallowed-positions.rs:122:8
+ |
+LL | if -let 0 = 0 {}
+ | ^^^^^^^^^^ cannot apply unary operator `-`
+
+error[E0277]: the `?` operator can only be applied to values that implement `Try`
+ --> $DIR/disallowed-positions.rs:132:8
+ |
+LL | if (let 0 = 0)? {}
+ | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
+ |
+ = help: the trait `Try` is not implemented for `bool`
+
+error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
+ --> $DIR/disallowed-positions.rs:132:19
+ |
+LL | fn nested_within_if_expr() {
+ | -------------------------- this function should return `Result` or `Option` to accept `?`
+...
+LL | if (let 0 = 0)? {}
+ | ^ cannot use the `?` operator in a function that returns `()`
+ |
+ = help: the trait `FromResidual<_>` is not implemented for `()`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:152:8
+ |
+LL | if x = let 0 = 0 {}
+ | ^^^^^^^^^^^^^ expected `bool`, found `()`
+ |
+help: you might have meant to compare for equality
+ |
+LL | if x == let 0 = 0 {}
+ | +
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:157:8
+ |
+LL | if true..(let 0 = 0) {}
+ | ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:161:8
+ |
+LL | if ..(let 0 = 0) {}
+ | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo`
+ |
+ = note: expected type `bool`
+ found struct `RangeTo<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:165:8
+ |
+LL | if (let 0 = 0).. {}
+ | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom`
+ |
+ = note: expected type `bool`
+ found struct `RangeFrom<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:171:12
+ |
+LL | if let Range { start: _, end: _ } = true..true && false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
+ | |
+ | expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:171:8
+ |
+LL | if let Range { start: _, end: _ } = true..true && false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:175:12
+ |
+LL | if let Range { start: _, end: _ } = true..true || false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
+ | |
+ | expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:175:8
+ |
+LL | if let Range { start: _, end: _ } = true..true || false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:182:12
+ |
+LL | if let Range { start: F, end } = F..|| true {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool`
+ | |
+ | expected fn pointer, found struct `Range`
+ |
+ = note: expected fn pointer `fn() -> bool`
+ found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:182:41
+ |
+LL | if let Range { start: F, end } = F..|| true {}
+ | ^^^^^^^ expected `bool`, found closure
+ |
+ = note: expected type `bool`
+ found closure `[closure@$DIR/disallowed-positions.rs:182:41: 182:43]`
+help: use parentheses to call this closure
+ |
+LL | if let Range { start: F, end } = F..(|| true)() {}
+ | + +++
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:182:8
+ |
+LL | if let Range { start: F, end } = F..|| true {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:190:12
+ |
+LL | if let Range { start: true, end } = t..&&false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool`
+ | |
+ | expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:190:44
+ |
+LL | if let Range { start: true, end } = t..&&false {}
+ | ^^^^^^^ expected `bool`, found `&&bool`
+ |
+help: consider removing the `&&`
+ |
+LL - if let Range { start: true, end } = t..&&false {}
+LL + if let Range { start: true, end } = t..false {}
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:190:8
+ |
+LL | if let Range { start: true, end } = t..&&false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<bool>`
+
+error[E0277]: the `?` operator can only be applied to values that implement `Try`
+ --> $DIR/disallowed-positions.rs:128:20
+ |
+LL | if let 0 = 0? {}
+ | ^^ the `?` operator cannot be applied to type `{integer}`
+ |
+ = help: the trait `Try` is not implemented for `{integer}`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:202:11
+ |
+LL | while &let 0 = 0 {}
+ | ^^^^^^^^^^ expected `bool`, found `&bool`
+ |
+help: consider removing the borrow
+ |
+LL - while &let 0 = 0 {}
+LL + while let 0 = 0 {}
+ |
+
+error[E0614]: type `bool` cannot be dereferenced
+ --> $DIR/disallowed-positions.rs:210:11
+ |
+LL | while *let 0 = 0 {}
+ | ^^^^^^^^^^
+
+error[E0600]: cannot apply unary operator `-` to type `bool`
+ --> $DIR/disallowed-positions.rs:214:11
+ |
+LL | while -let 0 = 0 {}
+ | ^^^^^^^^^^ cannot apply unary operator `-`
+
+error[E0277]: the `?` operator can only be applied to values that implement `Try`
+ --> $DIR/disallowed-positions.rs:224:11
+ |
+LL | while (let 0 = 0)? {}
+ | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
+ |
+ = help: the trait `Try` is not implemented for `bool`
+
+error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
+ --> $DIR/disallowed-positions.rs:224:22
+ |
+LL | fn nested_within_while_expr() {
+ | ----------------------------- this function should return `Result` or `Option` to accept `?`
+...
+LL | while (let 0 = 0)? {}
+ | ^ cannot use the `?` operator in a function that returns `()`
+ |
+ = help: the trait `FromResidual<_>` is not implemented for `()`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:244:11
+ |
+LL | while x = let 0 = 0 {}
+ | ^^^^^^^^^^^^^ expected `bool`, found `()`
+ |
+help: you might have meant to compare for equality
+ |
+LL | while x == let 0 = 0 {}
+ | +
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:249:11
+ |
+LL | while true..(let 0 = 0) {}
+ | ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:253:11
+ |
+LL | while ..(let 0 = 0) {}
+ | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo`
+ |
+ = note: expected type `bool`
+ found struct `RangeTo<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:257:11
+ |
+LL | while (let 0 = 0).. {}
+ | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom`
+ |
+ = note: expected type `bool`
+ found struct `RangeFrom<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:263:15
+ |
+LL | while let Range { start: _, end: _ } = true..true && false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
+ | |
+ | expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:263:11
+ |
+LL | while let Range { start: _, end: _ } = true..true && false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:267:15
+ |
+LL | while let Range { start: _, end: _ } = true..true || false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
+ | |
+ | expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:267:11
+ |
+LL | while let Range { start: _, end: _ } = true..true || false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:274:15
+ |
+LL | while let Range { start: F, end } = F..|| true {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool`
+ | |
+ | expected fn pointer, found struct `Range`
+ |
+ = note: expected fn pointer `fn() -> bool`
+ found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:274:44
+ |
+LL | while let Range { start: F, end } = F..|| true {}
+ | ^^^^^^^ expected `bool`, found closure
+ |
+ = note: expected type `bool`
+ found closure `[closure@$DIR/disallowed-positions.rs:274:44: 274:46]`
+help: use parentheses to call this closure
+ |
+LL | while let Range { start: F, end } = F..(|| true)() {}
+ | + +++
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:274:11
+ |
+LL | while let Range { start: F, end } = F..|| true {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<bool>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:282:15
+ |
+LL | while let Range { start: true, end } = t..&&false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool`
+ | |
+ | expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:282:47
+ |
+LL | while let Range { start: true, end } = t..&&false {}
+ | ^^^^^^^ expected `bool`, found `&&bool`
+ |
+help: consider removing the `&&`
+ |
+LL - while let Range { start: true, end } = t..&&false {}
+LL + while let Range { start: true, end } = t..false {}
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:282:11
+ |
+LL | while let Range { start: true, end } = t..&&false {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<bool>`
+
+error[E0277]: the `?` operator can only be applied to values that implement `Try`
+ --> $DIR/disallowed-positions.rs:220:23
+ |
+LL | while let 0 = 0? {}
+ | ^^ the `?` operator cannot be applied to type `{integer}`
+ |
+ = help: the trait `Try` is not implemented for `{integer}`
+
+error[E0614]: type `bool` cannot be dereferenced
+ --> $DIR/disallowed-positions.rs:311:5
+ |
+LL | *let 0 = 0;
+ | ^^^^^^^^^^
+
+error[E0600]: cannot apply unary operator `-` to type `bool`
+ --> $DIR/disallowed-positions.rs:315:5
+ |
+LL | -let 0 = 0;
+ | ^^^^^^^^^^ cannot apply unary operator `-`
+
+error[E0277]: the `?` operator can only be applied to values that implement `Try`
+ --> $DIR/disallowed-positions.rs:325:5
+ |
+LL | (let 0 = 0)?;
+ | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
+ |
+ = help: the trait `Try` is not implemented for `bool`
+
+error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
+ --> $DIR/disallowed-positions.rs:325:16
+ |
+LL | fn outside_if_and_while_expr() {
+ | ------------------------------ this function should return `Result` or `Option` to accept `?`
+...
+LL | (let 0 = 0)?;
+ | ^ cannot use the `?` operator in a function that returns `()`
+ |
+ = help: the trait `FromResidual<_>` is not implemented for `()`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:356:10
+ |
+LL | (let Range { start: _, end: _ } = true..true || false);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
+ | |
+ | expected `bool`, found struct `Range`
+ |
+ = note: expected type `bool`
+ found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+ --> $DIR/disallowed-positions.rs:379:5
+ |
+LL | fn outside_if_and_while_expr() {
+ | - help: try adding a return type: `-> &bool`
+...
+LL | &let 0 = 0
+ | ^^^^^^^^^^ expected `()`, found `&bool`
+
+error[E0277]: the `?` operator can only be applied to values that implement `Try`
+ --> $DIR/disallowed-positions.rs:321:17
+ |
+LL | let 0 = 0?;
+ | ^^ the `?` operator cannot be applied to type `{integer}`
+ |
+ = help: the trait `Try` is not implemented for `{integer}`
+
+error: aborting due to 215 previous errors
+
+Some errors have detailed explanations: E0277, E0308, E0600, E0614.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs b/tests/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
new file mode 100644
index 000000000..2a6c14435
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
@@ -0,0 +1,55 @@
+#![feature(let_chains)]
+
+fn main() {
+ let opt = Some(1i32);
+
+ let Some(n) = opt else {
+ return;
+ };
+ let Some(n) = opt && n == 1 else {
+ //~^ ERROR a `&&` expression cannot be directly assigned in `let...else`
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+ return;
+ };
+ let Some(n) = opt && let another = n else {
+ //~^ ERROR a `&&` expression cannot be directly assigned in `let...else`
+ //~| ERROR `let` expressions are not supported here
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+ //~| ERROR expected expression, found `let` statement
+ return;
+ };
+
+ if let Some(n) = opt else {
+ //~^ ERROR this `if` expression is missing a block after the condition
+ return;
+ };
+ if let Some(n) = opt && n == 1 else {
+ //~^ ERROR this `if` expression is missing a block after the condition
+ return;
+ };
+ if let Some(n) = opt && let another = n else {
+ //~^ ERROR this `if` expression is missing a block after the condition
+ return;
+ };
+
+ {
+ while let Some(n) = opt else {
+ //~^ ERROR expected `{`, found keyword `else`
+ return;
+ };
+ }
+ {
+ while let Some(n) = opt && n == 1 else {
+ //~^ ERROR expected `{`, found keyword `else`
+ return;
+ };
+ }
+ {
+ while let Some(n) = opt && let another = n else {
+ //~^ ERROR expected `{`, found keyword `else`
+ return;
+ };
+ }
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr b/tests/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr
new file mode 100644
index 000000000..498a112fa
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr
@@ -0,0 +1,142 @@
+error: a `&&` expression cannot be directly assigned in `let...else`
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:9:19
+ |
+LL | let Some(n) = opt && n == 1 else {
+ | ^^^^^^^^^^^^^
+ |
+help: wrap the expression in parentheses
+ |
+LL | let Some(n) = (opt && n == 1) else {
+ | + +
+
+error: expected expression, found `let` statement
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:26
+ |
+LL | let Some(n) = opt && let another = n else {
+ | ^^^
+
+error: a `&&` expression cannot be directly assigned in `let...else`
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19
+ |
+LL | let Some(n) = opt && let another = n else {
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: wrap the expression in parentheses
+ |
+LL | let Some(n) = (opt && let another = n) else {
+ | + +
+
+error: this `if` expression is missing a block after the condition
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:24:5
+ |
+LL | if let Some(n) = opt else {
+ | ^^
+ |
+help: add a block here
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:24:25
+ |
+LL | if let Some(n) = opt else {
+ | ^
+
+error: this `if` expression is missing a block after the condition
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:28:5
+ |
+LL | if let Some(n) = opt && n == 1 else {
+ | ^^
+ |
+help: add a block here
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:28:35
+ |
+LL | if let Some(n) = opt && n == 1 else {
+ | ^
+
+error: this `if` expression is missing a block after the condition
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:32:5
+ |
+LL | if let Some(n) = opt && let another = n else {
+ | ^^
+ |
+help: add a block here
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:32:44
+ |
+LL | if let Some(n) = opt && let another = n else {
+ | ^
+
+error: expected `{`, found keyword `else`
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:38:33
+ |
+LL | while let Some(n) = opt else {
+ | ----- ----------------- ^^^^ expected `{`
+ | | |
+ | | this `while` condition successfully parsed
+ | while parsing the body of this `while` expression
+
+error: expected `{`, found keyword `else`
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:44:43
+ |
+LL | while let Some(n) = opt && n == 1 else {
+ | ----- --------------------------- ^^^^ expected `{`
+ | | |
+ | | this `while` condition successfully parsed
+ | while parsing the body of this `while` expression
+
+error: expected `{`, found keyword `else`
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:50:52
+ |
+LL | while let Some(n) = opt && let another = n else {
+ | ----- ------------------------------------ ^^^^ expected `{`
+ | | |
+ | | this `while` condition successfully parsed
+ | while parsing the body of this `while` expression
+
+error: `let` expressions are not supported here
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:26
+ |
+LL | let Some(n) = opt && let another = n else {
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: only supported directly in conditions of `if` and `while` expressions
+
+error[E0308]: mismatched types
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:9:19
+ |
+LL | let Some(n) = opt && n == 1 else {
+ | ^^^ expected `bool`, found enum `Option`
+ |
+ = note: expected type `bool`
+ found enum `Option<i32>`
+
+error[E0308]: mismatched types
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:9:9
+ |
+LL | let Some(n) = opt && n == 1 else {
+ | ^^^^^^^ ------------- this expression has type `bool`
+ | |
+ | expected `bool`, found enum `Option`
+ |
+ = note: expected type `bool`
+ found enum `Option<_>`
+
+error[E0308]: mismatched types
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19
+ |
+LL | let Some(n) = opt && let another = n else {
+ | ^^^ expected `bool`, found enum `Option`
+ |
+ = note: expected type `bool`
+ found enum `Option<i32>`
+
+error[E0308]: mismatched types
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:9
+ |
+LL | let Some(n) = opt && let another = n else {
+ | ^^^^^^^ ---------------------- this expression has type `bool`
+ | |
+ | expected `bool`, found enum `Option`
+ |
+ = note: expected type `bool`
+ found enum `Option<_>`
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfc-2497-if-let-chains/feature-gate.rs b/tests/ui/rfc-2497-if-let-chains/feature-gate.rs
new file mode 100644
index 000000000..2b407ef51
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/feature-gate.rs
@@ -0,0 +1,62 @@
+// gate-test-let_chains
+
+// Here we test feature gating for ´let_chains`.
+// See `disallowed-positions.rs` for the grammar
+// defining the language for gated allowed positions.
+
+#![allow(irrefutable_let_patterns)]
+
+use std::ops::Range;
+
+fn _if() {
+ if let 0 = 1 {} // Stable!
+
+ if true && let 0 = 1 {}
+ //~^ ERROR `let` expressions in this position are unstable [E0658]
+
+ if let 0 = 1 && true {}
+ //~^ ERROR `let` expressions in this position are unstable [E0658]
+
+ 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() {
+ while let 0 = 1 {} // Stable!
+
+ while true && let 0 = 1 {}
+ //~^ ERROR `let` expressions in this position are unstable [E0658]
+
+ while let 0 = 1 && true {}
+ //~^ ERROR `let` expressions in this position are unstable [E0658]
+
+ while let Range { start: _, end: _ } = (true..true) && false {}
+ //~^ ERROR `let` expressions in this position are unstable [E0658]
+}
+
+fn _macros() {
+ macro_rules! noop_expr { ($e:expr) => {}; }
+
+ noop_expr!((let 0 = 1));
+ //~^ ERROR `let` expressions in this position are unstable [E0658]
+ //~| ERROR expected expression, found `let` statement
+
+ macro_rules! use_expr {
+ ($e:expr) => {
+ if $e {}
+ while $e {}
+ }
+ }
+ #[cfg(FALSE)] (let 0 = 1);
+ //~^ ERROR `let` expressions in this position are unstable [E0658]
+ //~| ERROR expected expression, found `let` statement
+ use_expr!(let 0 = 1);
+ //~^ ERROR no rules expected the token `let`
+}
+
+fn main() {}
diff --git a/tests/ui/rfc-2497-if-let-chains/feature-gate.stderr b/tests/ui/rfc-2497-if-let-chains/feature-gate.stderr
new file mode 100644
index 000000000..7a43b71fc
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/feature-gate.stderr
@@ -0,0 +1,120 @@
+error: expected expression, found `let` statement
+ --> $DIR/feature-gate.rs:55:20
+ |
+LL | #[cfg(FALSE)] (let 0 = 1);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/feature-gate.rs:45:17
+ |
+LL | noop_expr!((let 0 = 1));
+ | ^^^
+
+error: no rules expected the token `let`
+ --> $DIR/feature-gate.rs:58:15
+ |
+LL | macro_rules! use_expr {
+ | --------------------- when calling this macro
+...
+LL | use_expr!(let 0 = 1);
+ | ^^^ no rules expected this token in macro call
+ |
+note: while trying to match meta-variable `$e:expr`
+ --> $DIR/feature-gate.rs:50:10
+ |
+LL | ($e:expr) => {
+ | ^^^^^^^
+
+error[E0658]: `let` expressions in this position are unstable
+ --> $DIR/feature-gate.rs:14:16
+ |
+LL | if true && 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[E0658]: `let` expressions in this position are unstable
+ --> $DIR/feature-gate.rs:17:8
+ |
+LL | if let 0 = 1 && true {}
+ | ^^^^^^^^^
+ |
+ = 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:20:8
+ |
+LL | if let Range { start: _, end: _ } = (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: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 {}
+ | ^^^^^^^^^
+ |
+ = 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:35:11
+ |
+LL | while let 0 = 1 && true {}
+ | ^^^^^^^^^
+ |
+ = 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:38:11
+ |
+LL | while let Range { start: _, end: _ } = (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:55:20
+ |
+LL | #[cfg(FALSE)] (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[E0658]: `let` expressions in this position are unstable
+ --> $DIR/feature-gate.rs:45:17
+ |
+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 13 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs b/tests/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs
new file mode 100644
index 000000000..a942d1f4c
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs
@@ -0,0 +1,45 @@
+#![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
+ } {
+ }
+ }
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr b/tests/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr
new file mode 100644
index 000000000..d1ce83c72
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr
@@ -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
+
diff --git a/tests/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr b/tests/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr
new file mode 100644
index 000000000..be4a52315
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr
@@ -0,0 +1,115 @@
+error: leading irrefutable pattern in let chain
+ --> $DIR/irrefutable-lets.rs:13:8
+ |
+LL | if let first = &opt && let Some(ref second) = first && let None = second.start {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: this pattern will always match
+ = help: consider moving it outside of the construct
+note: the lint level is defined here
+ --> $DIR/irrefutable-lets.rs:6:30
+ |
+LL | #![cfg_attr(disallowed, deny(irrefutable_let_patterns))]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: irrefutable `if let` patterns
+ --> $DIR/irrefutable-lets.rs:19:8
+ |
+LL | if let first = &opt && let (a, b) = (1, 2) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: these patterns will always match, so the `if let` is useless
+ = help: consider replacing the `if let` with a `let`
+
+error: leading irrefutable pattern in let chain
+ --> $DIR/irrefutable-lets.rs:22:8
+ |
+LL | if let first = &opt && let Some(ref second) = first && let None = second.start && let v = 0 {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: this pattern will always match
+ = help: consider moving it outside of the construct
+
+error: trailing irrefutable pattern in let chain
+ --> $DIR/irrefutable-lets.rs:22:87
+ |
+LL | if let first = &opt && let Some(ref second) = first && let None = second.start && let v = 0 {}
+ | ^^^^^^^^^
+ |
+ = note: this pattern will always match
+ = help: consider moving it into the body
+
+error: trailing irrefutable patterns in let chain
+ --> $DIR/irrefutable-lets.rs:26:37
+ |
+LL | if let Some(ref first) = opt && let second = first && let _third = second {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: these patterns will always match
+ = help: consider moving them into the body
+
+error: leading irrefutable pattern in let chain
+ --> $DIR/irrefutable-lets.rs:29:8
+ |
+LL | if let Range { start: local_start, end: _ } = (None..Some(1)) && let None = local_start {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this pattern will always match
+ = help: consider moving it outside of the construct
+
+error: leading irrefutable pattern in let chain
+ --> $DIR/irrefutable-lets.rs:32:8
+ |
+LL | if let (a, b, c) = (Some(1), Some(1), Some(1)) && let None = Some(1) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this pattern will always match
+ = help: consider moving it outside of the construct
+
+error: leading irrefutable pattern in let chain
+ --> $DIR/irrefutable-lets.rs:35:8
+ |
+LL | if let first = &opt && let None = Some(1) {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: this pattern will always match
+ = help: consider moving it outside of the construct
+
+error: irrefutable `if let` guard patterns
+ --> $DIR/irrefutable-lets.rs:44:28
+ |
+LL | Some(ref first) if let second = first && let _third = second && let v = 4 + 4 => {},
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: these patterns will always match, so the guard is useless
+ = help: consider removing the guard and adding a `let` inside the match arm
+
+error: trailing irrefutable patterns in let chain
+ --> $DIR/irrefutable-lets.rs:59:16
+ |
+LL | && let v = local_end && let w = v => {},
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: these patterns will always match
+ = help: consider moving them into the body
+
+error: irrefutable `while let` patterns
+ --> $DIR/irrefutable-lets.rs:68:11
+ |
+LL | while let first = &opt && let (a, b) = (1, 2) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: these patterns will always match, so the loop will never exit
+ = help: consider instead using a `loop { ... }` with a `let` inside it
+
+error: trailing irrefutable patterns in let chain
+ --> $DIR/irrefutable-lets.rs:71:40
+ |
+LL | while let Some(ref first) = opt && let second = first && let _third = second {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: these patterns will always match
+ = help: consider moving them into the body
+
+error: aborting due to 12 previous errors
+
diff --git a/tests/ui/rfc-2497-if-let-chains/irrefutable-lets.rs b/tests/ui/rfc-2497-if-let-chains/irrefutable-lets.rs
new file mode 100644
index 000000000..9afb6853b
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/irrefutable-lets.rs
@@ -0,0 +1,78 @@
+// revisions: allowed disallowed
+//[allowed] check-pass
+
+#![feature(if_let_guard, let_chains)]
+#![cfg_attr(allowed, allow(irrefutable_let_patterns))]
+#![cfg_attr(disallowed, deny(irrefutable_let_patterns))]
+
+use std::ops::Range;
+
+fn main() {
+ let opt = Some(None..Some(1));
+
+ if let first = &opt && let Some(ref second) = first && let None = second.start {}
+ //[disallowed]~^ ERROR leading irrefutable pattern in let chain
+
+ // No lint as the irrefutable pattern is surrounded by other stuff
+ if 4 * 2 == 0 && let first = &opt && let Some(ref second) = first && let None = second.start {}
+
+ if let first = &opt && let (a, b) = (1, 2) {}
+ //[disallowed]~^ ERROR irrefutable `if let` patterns
+
+ if let first = &opt && let Some(ref second) = first && let None = second.start && let v = 0 {}
+ //[disallowed]~^ ERROR leading irrefutable pattern in let chain
+ //[disallowed]~^^ ERROR trailing irrefutable pattern in let chain
+
+ if let Some(ref first) = opt && let second = first && let _third = second {}
+ //[disallowed]~^ ERROR trailing irrefutable patterns in let chain
+
+ if let Range { start: local_start, end: _ } = (None..Some(1)) && let None = local_start {}
+ //[disallowed]~^ ERROR leading irrefutable pattern in let chain
+
+ if let (a, b, c) = (Some(1), Some(1), Some(1)) && let None = Some(1) {}
+ //[disallowed]~^ ERROR leading irrefutable pattern in let chain
+
+ if let first = &opt && let None = Some(1) {}
+ //[disallowed]~^ ERROR leading irrefutable pattern in let chain
+
+ if let Some(ref first) = opt
+ && let Range { start: local_start, end: _ } = first
+ && let None = local_start {
+ }
+
+ match opt {
+ Some(ref first) if let second = first && let _third = second && let v = 4 + 4 => {},
+ //[disallowed]~^ ERROR irrefutable `if let` guard patterns
+ _ => {}
+ }
+
+ // No error about leading irrefutable patterns: the expr on the rhs might
+ // use the bindings created by the match.
+ match opt {
+ Some(ref first) if let Range { start: local_start, end: _ } = first
+ && let None = local_start => {},
+ _ => {}
+ }
+
+ match opt {
+ Some(ref first) if let Range { start: Some(_), end: local_end } = first
+ && let v = local_end && let w = v => {},
+ //[disallowed]~^ ERROR trailing irrefutable patterns in let chain
+ _ => {}
+ }
+
+ // No error, despite the prefix being irrefutable: moving out could change the behaviour,
+ // due to possible side effects of the operation.
+ while let first = &opt && let Some(ref second) = first && let None = second.start {}
+
+ while let first = &opt && let (a, b) = (1, 2) {}
+ //[disallowed]~^ ERROR irrefutable `while let` patterns
+
+ while let Some(ref first) = opt && let second = first && let _third = second {}
+ //[disallowed]~^ ERROR trailing irrefutable patterns in let chain
+
+ while let Some(ref first) = opt
+ && let Range { start: local_start, end: _ } = first
+ && let None = local_start {
+ }
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/issue-88498.rs b/tests/ui/rfc-2497-if-let-chains/issue-88498.rs
new file mode 100644
index 000000000..3eb8a9ad0
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/issue-88498.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+pub enum UnOp {
+ Not(Vec<()>),
+}
+
+pub fn foo() {
+ if let Some(x) = None {
+ match x {
+ UnOp::Not(_) => {}
+ }
+ }
+}
+
+fn main() {
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/issue-90722.rs b/tests/ui/rfc-2497-if-let-chains/issue-90722.rs
new file mode 100644
index 000000000..6b7d88356
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/issue-90722.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+#![feature(let_chains)]
+
+fn main() {
+ let x = Some(vec!["test"]);
+
+ if let Some(v) = x && v.is_empty() {
+ println!("x == Some([])");
+ }
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/issue-92145.rs b/tests/ui/rfc-2497-if-let-chains/issue-92145.rs
new file mode 100644
index 000000000..7c7e31f4d
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/issue-92145.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+#![feature(let_chains)]
+
+fn main() {
+ let opt = Some("foo bar");
+
+ if true && let Some(x) = opt {
+ println!("{}", x);
+ }
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/issue-93150.rs b/tests/ui/rfc-2497-if-let-chains/issue-93150.rs
new file mode 100644
index 000000000..f90b9ab0d
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/issue-93150.rs
@@ -0,0 +1,8 @@
+fn main() {
+ match true {
+ _ if let true = true && true => {}
+ //~^ ERROR `if let` guards are
+ //~| ERROR `let` expressions in this
+ _ => {}
+ }
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/issue-93150.stderr b/tests/ui/rfc-2497-if-let-chains/issue-93150.stderr
new file mode 100644
index 000000000..b25f299a2
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/issue-93150.stderr
@@ -0,0 +1,22 @@
+error[E0658]: `if let` guards are experimental
+ --> $DIR/issue-93150.rs:3:11
+ |
+LL | _ if let true = true && true => {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #51114 <https://github.com/rust-lang/rust/issues/51114> for more information
+ = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
+ = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
+
+error[E0658]: `let` expressions in this position are unstable
+ --> $DIR/issue-93150.rs:3:14
+ |
+LL | _ if let true = true && true => {}
+ | ^^^^^^^^^^^^^^^
+ |
+ = 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 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/rfc-2497-if-let-chains/issue-99938.rs b/tests/ui/rfc-2497-if-let-chains/issue-99938.rs
new file mode 100644
index 000000000..bd81ce0b1
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/issue-99938.rs
@@ -0,0 +1,31 @@
+// compile-flags: -Zvalidate-mir -C opt-level=3
+// build-pass
+#![feature(let_chains)]
+struct TupleIter<T, I: Iterator<Item = T>> {
+ inner: I,
+}
+
+impl<T, I: Iterator<Item = T>> Iterator for TupleIter<T, I> {
+ type Item = (T, T, T);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let inner = &mut self.inner;
+
+ if let Some(first) = inner.next()
+ && let Some(second) = inner.next()
+ && let Some(third) = inner.next()
+ {
+ Some((first, second, third))
+ } else {
+ None
+ }
+ }
+}
+
+fn main() {
+ let vec: Vec<u8> = Vec::new();
+ let mut tup_iter = TupleIter {
+ inner: vec.into_iter(),
+ };
+ tup_iter.next();
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/no-double-assigments.rs b/tests/ui/rfc-2497-if-let-chains/no-double-assigments.rs
new file mode 100644
index 000000000..6b91c455e
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/no-double-assigments.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+fn main() {
+ loop {
+ // [1][0] should leave top scope
+ if true && [1][0] == 1 && true {
+ }
+ }
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/protect-precedences.rs b/tests/ui/rfc-2497-if-let-chains/protect-precedences.rs
new file mode 100644
index 000000000..fcc09b159
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/protect-precedences.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+#![allow(irrefutable_let_patterns)]
+
+fn main() {
+ let x: bool;
+ // This should associate as: `(x = (true && false));`.
+ x = true && false;
+ assert!(!x);
+
+ fn _f1() -> bool {
+ // Should associate as `(let _ = (return (true && false)))`.
+ if let _ = return true && false {};
+ //~^ WARNING unreachable block in `if`
+ }
+ assert!(!_f1());
+}
diff --git a/tests/ui/rfc-2497-if-let-chains/protect-precedences.stderr b/tests/ui/rfc-2497-if-let-chains/protect-precedences.stderr
new file mode 100644
index 000000000..24b35a2ab
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/protect-precedences.stderr
@@ -0,0 +1,12 @@
+warning: unreachable block in `if` or `while` expression
+ --> $DIR/protect-precedences.rs:13:41
+ |
+LL | if let _ = return true && false {};
+ | -------------------- ^^ unreachable block in `if` or `while` expression
+ | |
+ | any code following this expression is unreachable
+ |
+ = note: `#[warn(unreachable_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/rfc-2497-if-let-chains/then-else-blocks.rs b/tests/ui/rfc-2497-if-let-chains/then-else-blocks.rs
new file mode 100644
index 000000000..e061174f6
--- /dev/null
+++ b/tests/ui/rfc-2497-if-let-chains/then-else-blocks.rs
@@ -0,0 +1,49 @@
+// run-pass
+
+#![feature(if_let_guard, let_chains)]
+
+fn check_if_let(opt: Option<Option<Option<i32>>>, value: i32) -> bool {
+ if let Some(first) = opt
+ && let Some(second) = first
+ && let Some(third) = second
+ && third == value
+ {
+ true
+ }
+ else {
+ false
+ }
+}
+
+fn check_let_guard(opt: Option<Option<Option<i32>>>, value: i32) -> bool {
+ match opt {
+ Some(first) if let Some(second) = first && let Some(third) = second && third == value => {
+ true
+ }
+ _ => {
+ false
+ }
+ }
+}
+
+fn check_while_let(opt: Option<Option<Option<i32>>>, value: i32) -> bool {
+ while let Some(first) = opt
+ && let Some(second) = first
+ && let Some(third) = second
+ && third == value
+ {
+ return true;
+ }
+ false
+}
+
+fn main() {
+ assert_eq!(check_if_let(Some(Some(Some(1))), 1), true);
+ assert_eq!(check_if_let(Some(Some(Some(1))), 9), false);
+
+ assert_eq!(check_let_guard(Some(Some(Some(1))), 1), true);
+ assert_eq!(check_let_guard(Some(Some(Some(1))), 9), false);
+
+ assert_eq!(check_while_let(Some(Some(Some(1))), 1), true);
+ assert_eq!(check_while_let(Some(Some(Some(1))), 9), false);
+}