about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2022-08-20 20:40:08 +0200
committerNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2022-08-29 19:34:11 +0200
commitd1ef8180f956c9f1a7267e32491d65188f0aefd7 (patch)
treedc1e90fb68dbf6688bf2956e9336ffad353a9b91
parent76eb4f3bfdd5e7012268353a0a38b08b638253cd (diff)
downloadrust-d1ef8180f956c9f1a7267e32491d65188f0aefd7.tar.gz
rust-d1ef8180f956c9f1a7267e32491d65188f0aefd7.zip
Revert let_chains stabilization
This reverts commit 326646074940222d602f3683d0559088690830f4.

This is the revert against master, the beta revert was already done in #100538.
-rw-r--r--compiler/rustc_ast/src/lib.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs1
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs28
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs1
-rw-r--r--compiler/rustc_ast_passes/src/lib.rs1
-rw-r--r--compiler/rustc_attr/src/lib.rs1
-rw-r--r--compiler/rustc_borrowck/src/lib.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_error_messages/src/lib.rs1
-rw-r--r--compiler/rustc_errors/src/lib.rs1
-rw-r--r--compiler/rustc_expand/src/lib.rs1
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_infer/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_mir_build/src/lib.rs1
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs1
-rw-r--r--compiler/rustc_parse/src/lib.rs1
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs28
-rw-r--r--compiler/rustc_passes/src/lib.rs1
-rw-r--r--compiler/rustc_resolve/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/lib.rs1
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs1
-rw-r--r--compiler/rustc_typeck/src/lib.rs1
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/test/ui/expr/if/attrs/let-chains-attr.rs2
-rw-r--r--src/test/ui/expr/if/bad-if-let-suggestion.rs1
-rw-r--r--src/test/ui/expr/if/bad-if-let-suggestion.stderr21
-rw-r--r--src/test/ui/mir/issue-92893.rs1
-rw-r--r--src/test/ui/mir/issue-92893.stderr12
-rw-r--r--src/test/ui/mir/mir_let_chains_drop_order.rs1
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/feature-gate.rs30
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr178
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/allowed-syntax.rs30
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs1
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs11
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr564
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs2
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/feature-gate.rs62
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr114
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs2
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr12
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.rs2
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/issue-90722.rs2
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/issue-92145.rs2
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/issue-93150.rs1
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr11
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/then-else-blocks.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.fixed1
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.stderr32
59 files changed, 791 insertions, 396 deletions
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index f9b4d76f28f..27061f300a2 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -14,6 +14,7 @@
 #![feature(const_trait_impl)]
 #![feature(if_let_guard)]
 #![cfg_attr(bootstrap, feature(label_break_value))]
+#![feature(let_chains)]
 #![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(slice_internals)]
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index becb67d1165..5e9e8aa553d 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -31,6 +31,7 @@
 //! in the HIR, especially for multiple identifiers.
 
 #![feature(box_patterns)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(never_type)]
 #![recursion_limit = "256"]
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index b337e5328c5..b46274e4a76 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -119,7 +119,33 @@ impl<'a> AstValidator<'a> {
 
     /// Emits an error banning the `let` expression provided in the given location.
     fn ban_let_expr(&self, expr: &'a Expr, forbidden_let_reason: ForbiddenLetReason) {
-        self.session.emit_err(ForbiddenLet { span: expr.span, reason: forbidden_let_reason });
+        let sess = &self.session;
+        if sess.opts.unstable_features.is_nightly_build() {
+            let err = "`let` expressions are not supported here";
+            let mut diag = sess.struct_span_err(expr.span, err);
+            diag.note("only supported directly in conditions of `if` and `while` expressions");
+            match forbidden_let_reason {
+                ForbiddenLetReason::GenericForbidden => {}
+                ForbiddenLetReason::NotSupportedOr(span) => {
+                    diag.span_note(
+                        span,
+                        "`||` operators are not supported in let chain expressions",
+                    );
+                }
+                ForbiddenLetReason::NotSupportedParentheses(span) => {
+                    diag.span_note(
+                        span,
+                        "`let`s wrapped in parentheses are not supported in a context with let \
+                        chains",
+                    );
+                }
+            }
+            diag.emit();
+        } else {
+            sess.struct_span_err(expr.span, "expected expression, found statement (`let`)")
+                .note("variable declaration using `let` is a statement")
+                .emit();
+        }
     }
 
     fn check_gat_where(
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 4ac96ec8b60..6f7e88eb86f 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -777,6 +777,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
         "`if let` guards are experimental",
         "you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`"
     );
+    gate_all!(let_chains, "`let` expressions in this position are unstable");
     gate_all!(
         async_closure,
         "async closures are unstable",
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index 6a826298985..f282ff251bd 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -8,6 +8,7 @@
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
 #![feature(iter_is_partitioned)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![recursion_limit = "256"]
 
diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs
index 3a43f1aad02..053f848aacb 100644
--- a/compiler/rustc_attr/src/lib.rs
+++ b/compiler/rustc_attr/src/lib.rs
@@ -4,6 +4,7 @@
 //! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax`
 //! to this crate.
 
+#![feature(let_chains)]
 #![feature(let_else)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 0f8afb038f4..66fe49e9d12 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -2,6 +2,7 @@
 
 #![allow(rustc::potential_query_instability)]
 #![feature(box_patterns)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(never_type)]
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 48e81eb13c0..11565ba72d7 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -8,6 +8,7 @@
 #![feature(decl_macro)]
 #![feature(if_let_guard)]
 #![feature(is_sorted)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index c80ad692000..636d689a34b 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -6,6 +6,7 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(hash_raw_entry)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(extern_types)]
 #![feature(once_cell)]
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 7272ae5aa09..72ac6af685d 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -9,6 +9,7 @@ Rust MIR: a lowered representation of Rust.
 #![feature(control_flow_enum)]
 #![feature(decl_macro)]
 #![feature(exact_size_is_empty)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index b17668dc0ae..d1ac326a72c 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -1,3 +1,4 @@
+#![feature(let_chains)]
 #![feature(once_cell)]
 #![feature(rustc_attrs)]
 #![feature(type_alias_impl_trait)]
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 9b9c334d4df..7b0f4354afd 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -6,6 +6,7 @@
 #![feature(drain_filter)]
 #![feature(if_let_guard)]
 #![feature(adt_const_params)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(never_type)]
 #![feature(result_option_inspect)]
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index e1dde1672c1..75dcbd69674 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -2,6 +2,7 @@
 #![feature(associated_type_bounds)]
 #![feature(associated_type_defaults)]
 #![feature(if_let_guard)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(macro_metavar_expr)]
 #![feature(proc_macro_diagnostic)]
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index fb1ad8d6beb..c22adf77a27 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -188,8 +188,6 @@ declare_features! (
     (accepted, item_like_imports, "1.15.0", Some(35120), None),
     /// Allows `'a: { break 'a; }`.
     (accepted, label_break_value, "CURRENT_RUSTC_VERSION", Some(48594), None),
-    /// Allows `if/while p && let q = r && ...` chains.
-    (accepted, let_chains, "1.64.0", Some(53667), None),
     /// Allows `break {expr}` with a value inside `loop`s.
     (accepted, loop_break_value, "1.19.0", Some(37339), None),
     /// Allows use of `?` as the Kleene "at most one" operator in macros.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 22178dd2123..a5091621f66 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -422,6 +422,8 @@ declare_features! (
     (active, isa_attribute, "1.48.0", Some(74727), None),
     // Allows setting the threshold for the `large_assignments` lint.
     (active, large_assignments, "1.52.0", Some(83518), None),
+    /// Allows `if/while p && let q = r && ...` chains.
+    (active, let_chains, "1.37.0", Some(53667), None),
     /// Allows `let...else` statements.
     (active, let_else, "1.56.0", Some(87335), None),
     /// Allows `#[link(..., cfg(..))]`.
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 602a9ab13f3..931ebca7d01 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -18,6 +18,7 @@
 #![feature(control_flow_enum)]
 #![feature(extend_one)]
 #![cfg_attr(bootstrap, feature(label_break_value))]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(never_type)]
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index f34e062fd12..c3065e4a2d9 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -33,6 +33,7 @@
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
 #![feature(iter_order_by)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(never_type)]
 #![recursion_limit = "256"]
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 75069a5f0dc..6440f3e390c 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -4,6 +4,7 @@
 #![feature(generators)]
 #![feature(generic_associated_types)]
 #![feature(iter_from_generator)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(once_cell)]
 #![feature(proc_macro_internals)]
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 6a6505d0256..be9e5865e54 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -39,6 +39,7 @@
 #![feature(extern_types)]
 #![feature(new_uninit)]
 #![feature(once_cell)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(trusted_len)]
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index e51ca65dc16..11cd2a9aa4d 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -5,6 +5,7 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(if_let_guard)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(once_cell)]
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 56fb601d2b5..75851bf9dfd 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -1,5 +1,6 @@
 #![allow(rustc::potential_query_instability)]
 #![feature(box_patterns)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 3691d82a835..3c88e1ef377 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -3,6 +3,7 @@
 #![feature(array_windows)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 18aa109d7a6..c8541609514 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2251,7 +2251,15 @@ impl<'a> Parser<'a> {
 
     /// Parses the condition of a `if` or `while` expression.
     fn parse_cond_expr(&mut self) -> PResult<'a, P<Expr>> {
-        self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, None)
+        let cond =
+            self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, None)?;
+
+        if let ExprKind::Let(..) = cond.kind {
+            // Remove the last feature gating of a `let` expression since it's stable.
+            self.sess.gated_spans.ungate_last(sym::let_chains, cond.span);
+        }
+
+        Ok(cond)
     }
 
     /// Parses a `let $pat = $expr` pseudo-expression.
@@ -2280,6 +2288,7 @@ impl<'a> Parser<'a> {
             this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
         })?;
         let span = lo.to(expr.span);
+        self.sess.gated_spans.gate(sym::let_chains, span);
         Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span)))
     }
 
@@ -2571,13 +2580,15 @@ impl<'a> Parser<'a> {
     pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
         // Used to check the `let_chains` and `if_let_guard` features mostly by scaning
         // `&&` tokens.
-        fn check_let_expr(expr: &Expr) -> bool {
+        fn check_let_expr(expr: &Expr) -> (bool, bool) {
             match expr.kind {
                 ExprKind::Binary(BinOp { node: BinOpKind::And, .. }, ref lhs, ref rhs) => {
-                    check_let_expr(lhs) || check_let_expr(rhs)
+                    let lhs_rslt = check_let_expr(lhs);
+                    let rhs_rslt = check_let_expr(rhs);
+                    (lhs_rslt.0 || rhs_rslt.0, false)
                 }
-                ExprKind::Let(..) => true,
-                _ => false,
+                ExprKind::Let(..) => (true, true),
+                _ => (false, true),
             }
         }
         let attrs = self.parse_outer_attributes()?;
@@ -2592,7 +2603,12 @@ impl<'a> Parser<'a> {
             let guard = if this.eat_keyword(kw::If) {
                 let if_span = this.prev_token.span;
                 let cond = this.parse_expr_res(Restrictions::ALLOW_LET, None)?;
-                if check_let_expr(&cond) {
+                let (has_let_expr, does_not_have_bin_op) = check_let_expr(&cond);
+                if has_let_expr {
+                    if does_not_have_bin_op {
+                        // Remove the last feature gating of a `let` expression since it's stable.
+                        this.sess.gated_spans.ungate_last(sym::let_chains, cond.span);
+                    }
                     let span = if_span.to(cond.span);
                     this.sess.gated_spans.gate(sym::if_let_guard, span);
                 }
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 4af041dac0d..7b2f83958af 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -7,6 +7,7 @@
 #![allow(rustc::potential_query_instability)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(iter_intersperse)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index eb727debc91..d91a58b13ff 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -11,6 +11,7 @@
 #![feature(drain_filter)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(never_type)]
 #![recursion_limit = "256"]
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 0617bd5fae7..7353c1ca0e2 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,4 +1,5 @@
 #![feature(if_let_guard)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(never_type)]
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index e0dd28bee30..77cc2c164c3 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -17,6 +17,7 @@
 #![feature(drain_filter)]
 #![feature(hash_drain_filter)]
 #![cfg_attr(bootstrap, feature(label_break_value))]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(if_let_guard)]
 #![feature(never_type)]
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index 5699f642baf..8e910441a5d 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -65,6 +65,7 @@ This API is completely unstable and subject to change.
 #![feature(is_sorted)]
 #![feature(iter_intersperse)]
 #![cfg_attr(bootstrap, feature(label_break_value))]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(never_type)]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index f5dcdab4cd5..b0fef492d92 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -254,6 +254,7 @@
 #![feature(intra_doc_pointers)]
 #![cfg_attr(bootstrap, feature(label_break_value))]
 #![feature(lang_items)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(linkage)]
 #![feature(link_cfg)]
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 8aede1e77a2..92380d12429 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -8,6 +8,7 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(drain_filter)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(test)]
 #![feature(never_type)]
diff --git a/src/test/ui/expr/if/attrs/let-chains-attr.rs b/src/test/ui/expr/if/attrs/let-chains-attr.rs
index d62c2cb403f..2cd8731141a 100644
--- a/src/test/ui/expr/if/attrs/let-chains-attr.rs
+++ b/src/test/ui/expr/if/attrs/let-chains-attr.rs
@@ -1,5 +1,7 @@
 // check-pass
 
+#![feature(let_chains)]
+
 #[cfg(FALSE)]
 fn foo() {
     #[attr]
diff --git a/src/test/ui/expr/if/bad-if-let-suggestion.rs b/src/test/ui/expr/if/bad-if-let-suggestion.rs
index 070a5b20128..a8b2a283039 100644
--- a/src/test/ui/expr/if/bad-if-let-suggestion.rs
+++ b/src/test/ui/expr/if/bad-if-let-suggestion.rs
@@ -4,6 +4,7 @@
 fn a() {
     if let x = 1 && i = 2 {}
     //~^ ERROR cannot find value `i` in this scope
+    //~| ERROR `let` expressions in this position are unstable
     //~| ERROR mismatched types
     //~| ERROR `let` expressions are not supported here
 }
diff --git a/src/test/ui/expr/if/bad-if-let-suggestion.stderr b/src/test/ui/expr/if/bad-if-let-suggestion.stderr
index 9f7a21c7d1a..60d286fedf5 100644
--- a/src/test/ui/expr/if/bad-if-let-suggestion.stderr
+++ b/src/test/ui/expr/if/bad-if-let-suggestion.stderr
@@ -13,7 +13,7 @@ LL |     if let x = 1 && i = 2 {}
    |                     ^ not found in this scope
 
 error[E0425]: cannot find value `i` in this scope
-  --> $DIR/bad-if-let-suggestion.rs:12:9
+  --> $DIR/bad-if-let-suggestion.rs:13:9
    |
 LL | fn a() {
    | ------ similarly named function `a` defined here
@@ -22,7 +22,7 @@ LL |     if (i + j) = i {}
    |         ^ help: a function with a similar name exists: `a`
 
 error[E0425]: cannot find value `j` in this scope
-  --> $DIR/bad-if-let-suggestion.rs:12:13
+  --> $DIR/bad-if-let-suggestion.rs:13:13
    |
 LL | fn a() {
    | ------ similarly named function `a` defined here
@@ -31,7 +31,7 @@ LL |     if (i + j) = i {}
    |             ^ help: a function with a similar name exists: `a`
 
 error[E0425]: cannot find value `i` in this scope
-  --> $DIR/bad-if-let-suggestion.rs:12:18
+  --> $DIR/bad-if-let-suggestion.rs:13:18
    |
 LL | fn a() {
    | ------ similarly named function `a` defined here
@@ -40,7 +40,7 @@ LL |     if (i + j) = i {}
    |                  ^ help: a function with a similar name exists: `a`
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/bad-if-let-suggestion.rs:19:8
+  --> $DIR/bad-if-let-suggestion.rs:20:8
    |
 LL | fn a() {
    | ------ similarly named function `a` defined here
@@ -48,13 +48,22 @@ LL | fn a() {
 LL |     if x[0] = 1 {}
    |        ^ help: a function with a similar name exists: `a`
 
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/bad-if-let-suggestion.rs:5:8
+   |
+LL |     if let x = 1 && i = 2 {}
+   |        ^^^^^^^^^
+   |
+   = 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[E0308]: mismatched types
   --> $DIR/bad-if-let-suggestion.rs:5:8
    |
 LL |     if let x = 1 && i = 2 {}
    |        ^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
-Some errors have detailed explanations: E0308, E0425.
+Some errors have detailed explanations: E0308, E0425, E0658.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/mir/issue-92893.rs b/src/test/ui/mir/issue-92893.rs
index c2827c7e37f..635050f376c 100644
--- a/src/test/ui/mir/issue-92893.rs
+++ b/src/test/ui/mir/issue-92893.rs
@@ -1,5 +1,6 @@
 struct Bug<A = [(); (let a = (), 1).1]> {
     //~^ `let` expressions are not supported here
+    //~| `let` expressions in this position are unstable [E0658]
     //~| expected expression, found `let` statement
     a: A
 }
diff --git a/src/test/ui/mir/issue-92893.stderr b/src/test/ui/mir/issue-92893.stderr
index bd4654edf4b..4a0fcce31d7 100644
--- a/src/test/ui/mir/issue-92893.stderr
+++ b/src/test/ui/mir/issue-92893.stderr
@@ -12,5 +12,15 @@ LL | struct Bug<A = [(); (let a = (), 1).1]> {
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 
-error: aborting due to 2 previous errors
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/issue-92893.rs:1:22
+   |
+LL | struct Bug<A = [(); (let a = (), 1).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 3 previous errors
 
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/mir/mir_let_chains_drop_order.rs b/src/test/ui/mir/mir_let_chains_drop_order.rs
index 21e7b5070af..6498a519571 100644
--- a/src/test/ui/mir/mir_let_chains_drop_order.rs
+++ b/src/test/ui/mir/mir_let_chains_drop_order.rs
@@ -4,6 +4,7 @@
 
 // See `mir_drop_order.rs` for more information
 
+#![feature(let_chains)]
 #![allow(irrefutable_let_patterns)]
 
 use std::cell::RefCell;
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
index 0fe50932b4b..f0105e08e27 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
@@ -8,35 +8,49 @@ fn _if_let_guard() {
         //~^ ERROR `if let` guards are experimental
 
         () if (let 0 = 1) => {}
-        //~^ ERROR expected expression, found `let` statement
+        //~^ ERROR `let` expressions in this position are unstable
+        //~| ERROR expected expression, found `let` statement
 
         () if (((let 0 = 1))) => {}
-        //~^ ERROR expected expression, found `let` statement
+        //~^ ERROR `let` expressions in this position are unstable
+        //~| ERROR expected expression, found `let` statement
 
         () if true && let 0 = 1 => {}
         //~^ ERROR `if let` guards are experimental
+        //~| ERROR `let` expressions in this position are unstable
 
         () if let 0 = 1 && true => {}
         //~^ ERROR `if let` guards are experimental
+        //~| ERROR `let` expressions in this position are unstable
 
         () if (let 0 = 1) && true => {}
-        //~^ ERROR expected expression, found `let` statement
+        //~^ ERROR `let` expressions in this position are unstable
+        //~| ERROR expected expression, found `let` statement
 
         () if true && (let 0 = 1) => {}
-        //~^ ERROR expected expression, found `let` statement
+        //~^ ERROR `let` expressions in this position are unstable
+        //~| ERROR expected expression, found `let` statement
 
         () if (let 0 = 1) && (let 0 = 1) => {}
-        //~^ ERROR expected expression, found `let` statement
+        //~^ ERROR `let` expressions in this position are unstable
+        //~| ERROR `let` expressions in this position are unstable
+        //~| ERROR expected expression, found `let` statement
         //~| ERROR expected expression, found `let` statement
 
         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
         //~^ ERROR `if let` guards are experimental
+        //~| ERROR `let` expressions in this position are unstable
+        //~| ERROR `let` expressions in this position are unstable
+        //~| ERROR `let` expressions in this position are unstable
+        //~| ERROR `let` expressions in this position are unstable
+        //~| ERROR `let` expressions in this position are unstable
         //~| ERROR expected expression, found `let` statement
         //~| ERROR expected expression, found `let` statement
         //~| ERROR expected expression, found `let` statement
 
         () if let Range { start: _, end: _ } = (true..true) && false => {}
         //~^ ERROR `if let` guards are experimental
+        //~| ERROR `let` expressions in this position are unstable
 
         _ => {}
     }
@@ -52,9 +66,11 @@ fn _macros() {
         }
     }
     use_expr!((let 0 = 1 && 0 == 0));
-    //~^ ERROR expected expression, found `let` statement
+    //~^ ERROR `let` expressions in this position are unstable
+    //~| ERROR expected expression, found `let` statement
     use_expr!((let 0 = 1));
-    //~^ ERROR expected expression, found `let` statement
+    //~^ ERROR `let` expressions in this position are unstable
+    //~| ERROR expected expression, found `let` statement
     match () {
         #[cfg(FALSE)]
         () if let 0 = 1 => {}
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
index 35db84a6cb7..e017d04a5c9 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
@@ -5,67 +5,67 @@ LL |         () if (let 0 = 1) => {}
    |                ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/feature-gate.rs:13:18
+  --> $DIR/feature-gate.rs:14:18
    |
 LL |         () if (((let 0 = 1))) => {}
    |                  ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/feature-gate.rs:22:16
+  --> $DIR/feature-gate.rs:26:16
    |
 LL |         () if (let 0 = 1) && true => {}
    |                ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/feature-gate.rs:25:24
+  --> $DIR/feature-gate.rs:30:24
    |
 LL |         () if true && (let 0 = 1) => {}
    |                        ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/feature-gate.rs:28:16
+  --> $DIR/feature-gate.rs:34:16
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/feature-gate.rs:28:31
+  --> $DIR/feature-gate.rs:34:31
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                               ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/feature-gate.rs:32:42
+  --> $DIR/feature-gate.rs:40:42
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                          ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/feature-gate.rs:32:55
+  --> $DIR/feature-gate.rs:40:55
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                       ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/feature-gate.rs:32:68
+  --> $DIR/feature-gate.rs:40:68
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                                    ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/feature-gate.rs:54:16
+  --> $DIR/feature-gate.rs:68:16
    |
 LL |     use_expr!((let 0 = 1 && 0 == 0));
    |                ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/feature-gate.rs:56:16
+  --> $DIR/feature-gate.rs:71:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^
 
 error: no rules expected the token `let`
-  --> $DIR/feature-gate.rs:64:15
+  --> $DIR/feature-gate.rs:80:15
    |
 LL |     macro_rules! use_expr {
    |     --------------------- when calling this macro
@@ -84,7 +84,7 @@ LL |         () if let 0 = 1 => {}
    = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
 
 error[E0658]: `if let` guards are experimental
-  --> $DIR/feature-gate.rs:16:12
+  --> $DIR/feature-gate.rs:18:12
    |
 LL |         () if true && let 0 = 1 => {}
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -94,7 +94,7 @@ LL |         () if true && let 0 = 1 => {}
    = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
 
 error[E0658]: `if let` guards are experimental
-  --> $DIR/feature-gate.rs:19:12
+  --> $DIR/feature-gate.rs:22:12
    |
 LL |         () if let 0 = 1 && true => {}
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -104,7 +104,7 @@ LL |         () if let 0 = 1 && true => {}
    = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
 
 error[E0658]: `if let` guards are experimental
-  --> $DIR/feature-gate.rs:32:12
+  --> $DIR/feature-gate.rs:40:12
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -114,7 +114,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
 
 error[E0658]: `if let` guards are experimental
-  --> $DIR/feature-gate.rs:38:12
+  --> $DIR/feature-gate.rs:51:12
    |
 LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -124,7 +124,7 @@ LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
 
 error[E0658]: `if let` guards are experimental
-  --> $DIR/feature-gate.rs:60:12
+  --> $DIR/feature-gate.rs:76:12
    |
 LL |         () if let 0 = 1 => {}
    |            ^^^^^^^^^^^^
@@ -133,6 +133,150 @@ LL |         () if let 0 = 1 => {}
    = 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: aborting due to 18 previous errors
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/feature-gate.rs:10:16
+   |
+LL |         () if (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:14:18
+   |
+LL |         () if (((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:18:23
+   |
+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:22:15
+   |
+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:26:16
+   |
+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:30:24
+   |
+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:34:16
+   |
+LL |         () if (let 0 = 1) && (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:34:31
+   |
+LL |         () if (let 0 = 1) && (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:40:15
+   |
+LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
+   |               ^^^^^^^^^
+   |
+   = 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:40:28
+   |
+LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
+   |                            ^^^^^^^^^
+   |
+   = 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:40:42
+   |
+LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
+   |                                          ^^^^^^^^^
+   |
+   = 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:40:55
+   |
+LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
+   |                                                       ^^^^^^^^^
+   |
+   = 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:40:68
+   |
+LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
+   |                                                                    ^^^^^^^^^
+   |
+   = 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:51:15
+   |
+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:68:16
+   |
+LL |     use_expr!((let 0 = 1 && 0 == 0));
+   |                ^^^^^^^^^
+   |
+   = 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:71:16
+   |
+LL |     use_expr!((let 0 = 1));
+   |                ^^^^^^^^^
+   |
+   = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
+   = help: add `#![feature(let_chains)]` to the crate attributes to enable
+
+error: aborting due to 34 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2497-if-let-chains/allowed-syntax.rs b/src/test/ui/rfc-2497-if-let-chains/allowed-syntax.rs
deleted file mode 100644
index ffe0499fda2..00000000000
--- a/src/test/ui/rfc-2497-if-let-chains/allowed-syntax.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// check-pass
-
-#![allow(irrefutable_let_patterns)]
-
-use std::ops::Range;
-
-fn _if() {
-    if let 0 = 1 {}
-
-    if true && let 0 = 1 {}
-
-    if let 0 = 1 && true {}
-
-    if let Range { start: _, end: _ } = (true..true) && false {}
-
-    if let 1 = 1 && let true = { true } && false {
-    }
-}
-
-fn _while() {
-    while let 0 = 1 {}
-
-    while true && let 0 = 1 {}
-
-    while let 0 = 1 && true {}
-
-    while let Range { start: _, end: _ } = (true..true) && false {}
-}
-
-fn main() {}
diff --git a/src/test/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs b/src/test/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs
index 82164bda489..d851fac8e64 100644
--- a/src/test/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs
@@ -1,5 +1,6 @@
 // run-pass
 
+#![feature(let_chains)]
 #![allow(irrefutable_let_patterns)]
 
 fn main() {
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
index e8f1ff9c3fd..2a9a5472b2e 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
@@ -17,6 +17,8 @@
 //
 // 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;
@@ -102,12 +104,6 @@ fn _macros() {
     //~^ ERROR `let` expressions are not supported here
     //~| ERROR `let` expressions are not supported here
     //~| ERROR expected expression, found `let` statement
-    use_expr!(true && let 0 = 1);
-    //~^ ERROR expected expression, found `let` statement
-
-    macro_rules! noop_expr { ($e:expr) => {}; }
-    noop_expr!((let 0 = 1));
-    //~^ ERROR expected expression, found `let` statement
 }
 
 fn nested_within_if_expr() {
@@ -481,7 +477,4 @@ fn with_parenthesis() {
         ([1, 2, 3][let _ = ()])
         //~^ ERROR expected expression, found `let` statement
     }
-
-    #[cfg(FALSE)] (let 0 = 1);
-    //~^ ERROR expected expression, found `let` statement
 }
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index d5d82166a4a..fce0cdfe0d5 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -1,413 +1,413 @@
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:27:9
+  --> $DIR/disallowed-positions.rs:29:9
    |
 LL |     if (let 0 = 1) {}
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:31:11
+  --> $DIR/disallowed-positions.rs:33:11
    |
 LL |     if (((let 0 = 1))) {}
    |           ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:35:9
+  --> $DIR/disallowed-positions.rs:37:9
    |
 LL |     if (let 0 = 1) && true {}
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:39:17
+  --> $DIR/disallowed-positions.rs:41:17
    |
 LL |     if true && (let 0 = 1) {}
    |                 ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:43:9
+  --> $DIR/disallowed-positions.rs:45:9
    |
 LL |     if (let 0 = 1) && (let 0 = 1) {}
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:43:24
+  --> $DIR/disallowed-positions.rs:45:24
    |
 LL |     if (let 0 = 1) && (let 0 = 1) {}
    |                        ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:49:35
+  --> $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:49:48
+  --> $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:49:61
+  --> $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:59:12
+  --> $DIR/disallowed-positions.rs:61:12
    |
 LL |     while (let 0 = 1) {}
    |            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:63:14
+  --> $DIR/disallowed-positions.rs:65:14
    |
 LL |     while (((let 0 = 1))) {}
    |              ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:67:12
+  --> $DIR/disallowed-positions.rs:69:12
    |
 LL |     while (let 0 = 1) && true {}
    |            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:71:20
+  --> $DIR/disallowed-positions.rs:73:20
    |
 LL |     while true && (let 0 = 1) {}
    |                    ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:75:12
+  --> $DIR/disallowed-positions.rs:77:12
    |
 LL |     while (let 0 = 1) && (let 0 = 1) {}
    |            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:75:27
+  --> $DIR/disallowed-positions.rs:77:27
    |
 LL |     while (let 0 = 1) && (let 0 = 1) {}
    |                           ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:81:38
+  --> $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:81:51
+  --> $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:81:64
+  --> $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:114:9
+  --> $DIR/disallowed-positions.rs:110:9
    |
 LL |     if &let 0 = 0 {}
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:119:9
+  --> $DIR/disallowed-positions.rs:115:9
    |
 LL |     if !let 0 = 0 {}
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:122:9
+  --> $DIR/disallowed-positions.rs:118:9
    |
 LL |     if *let 0 = 0 {}
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:126:9
+  --> $DIR/disallowed-positions.rs:122:9
    |
 LL |     if -let 0 = 0 {}
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:136:9
+  --> $DIR/disallowed-positions.rs:132:9
    |
 LL |     if (let 0 = 0)? {}
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:142:16
+  --> $DIR/disallowed-positions.rs:138:16
    |
 LL |     if true || let 0 = 0 {}
    |                ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:145:17
+  --> $DIR/disallowed-positions.rs:141:17
    |
 LL |     if (true || let 0 = 0) {}
    |                 ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:148:25
+  --> $DIR/disallowed-positions.rs:144:25
    |
 LL |     if true && (true || let 0 = 0) {}
    |                         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:151:25
+  --> $DIR/disallowed-positions.rs:147:25
    |
 LL |     if true || (true && let 0 = 0) {}
    |                         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:156:12
+  --> $DIR/disallowed-positions.rs:152:12
    |
 LL |     if x = let 0 = 0 {}
    |            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:161:15
+  --> $DIR/disallowed-positions.rs:157:15
    |
 LL |     if true..(let 0 = 0) {}
    |               ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:165:11
+  --> $DIR/disallowed-positions.rs:161:11
    |
 LL |     if ..(let 0 = 0) {}
    |           ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:169:9
+  --> $DIR/disallowed-positions.rs:165:9
    |
 LL |     if (let 0 = 0).. {}
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:200:19
+  --> $DIR/disallowed-positions.rs:196:19
    |
 LL |     if let true = let true = true {}
    |                   ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:206:12
+  --> $DIR/disallowed-positions.rs:202:12
    |
 LL |     while &let 0 = 0 {}
    |            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:211:12
+  --> $DIR/disallowed-positions.rs:207:12
    |
 LL |     while !let 0 = 0 {}
    |            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:214:12
+  --> $DIR/disallowed-positions.rs:210:12
    |
 LL |     while *let 0 = 0 {}
    |            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:218:12
+  --> $DIR/disallowed-positions.rs:214:12
    |
 LL |     while -let 0 = 0 {}
    |            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:228:12
+  --> $DIR/disallowed-positions.rs:224:12
    |
 LL |     while (let 0 = 0)? {}
    |            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:234:19
+  --> $DIR/disallowed-positions.rs:230:19
    |
 LL |     while true || let 0 = 0 {}
    |                   ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:237:20
+  --> $DIR/disallowed-positions.rs:233:20
    |
 LL |     while (true || let 0 = 0) {}
    |                    ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:240:28
+  --> $DIR/disallowed-positions.rs:236:28
    |
 LL |     while true && (true || let 0 = 0) {}
    |                            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:243:28
+  --> $DIR/disallowed-positions.rs:239:28
    |
 LL |     while true || (true && let 0 = 0) {}
    |                            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:248:15
+  --> $DIR/disallowed-positions.rs:244:15
    |
 LL |     while x = let 0 = 0 {}
    |               ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:253:18
+  --> $DIR/disallowed-positions.rs:249:18
    |
 LL |     while true..(let 0 = 0) {}
    |                  ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:257:14
+  --> $DIR/disallowed-positions.rs:253:14
    |
 LL |     while ..(let 0 = 0) {}
    |              ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:261:12
+  --> $DIR/disallowed-positions.rs:257:12
    |
 LL |     while (let 0 = 0).. {}
    |            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:292:22
+  --> $DIR/disallowed-positions.rs:288:22
    |
 LL |     while let true = let true = true {}
    |                      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:308:6
+  --> $DIR/disallowed-positions.rs:304:6
    |
 LL |     &let 0 = 0;
    |      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:312:6
+  --> $DIR/disallowed-positions.rs:308:6
    |
 LL |     !let 0 = 0;
    |      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:315:6
+  --> $DIR/disallowed-positions.rs:311:6
    |
 LL |     *let 0 = 0;
    |      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:319:6
+  --> $DIR/disallowed-positions.rs:315:6
    |
 LL |     -let 0 = 0;
    |      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:329:6
+  --> $DIR/disallowed-positions.rs:325:6
    |
 LL |     (let 0 = 0)?;
    |      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:335:13
+  --> $DIR/disallowed-positions.rs:331:13
    |
 LL |     true || let 0 = 0;
    |             ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:338:14
+  --> $DIR/disallowed-positions.rs:334:14
    |
 LL |     (true || let 0 = 0);
    |              ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:341:22
+  --> $DIR/disallowed-positions.rs:337:22
    |
 LL |     true && (true || let 0 = 0);
    |                      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:346:9
+  --> $DIR/disallowed-positions.rs:342:9
    |
 LL |     x = let 0 = 0;
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:350:12
+  --> $DIR/disallowed-positions.rs:346:12
    |
 LL |     true..(let 0 = 0);
    |            ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:353:8
+  --> $DIR/disallowed-positions.rs:349:8
    |
 LL |     ..(let 0 = 0);
    |        ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:356:6
+  --> $DIR/disallowed-positions.rs:352:6
    |
 LL |     (let 0 = 0)..;
    |      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:360:6
+  --> $DIR/disallowed-positions.rs:356:6
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:365:6
+  --> $DIR/disallowed-positions.rs:361:6
    |
 LL |     (let true = let true = true);
    |      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:365:17
+  --> $DIR/disallowed-positions.rs:361:17
    |
 LL |     (let true = let true = true);
    |                 ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:372:25
+  --> $DIR/disallowed-positions.rs:368:25
    |
 LL |         let x = true && let y = 1;
    |                         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:378:19
+  --> $DIR/disallowed-positions.rs:374:19
    |
 LL |         [1, 2, 3][let _ = ()]
    |                   ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:383:6
+  --> $DIR/disallowed-positions.rs:379:6
    |
 LL |     &let 0 = 0
    |      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:395:17
+  --> $DIR/disallowed-positions.rs:391:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:401:17
+  --> $DIR/disallowed-positions.rs:397:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:407:17
+  --> $DIR/disallowed-positions.rs:403:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:419:17
+  --> $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:419:9
+  --> $DIR/disallowed-positions.rs:415:9
    |
 LL |         true && let 1 = 1
    |         ^^^^^^^^^^^^^^^^^
@@ -418,389 +418,371 @@ LL |         { true && let 1 = 1 }
    |         +                   +
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:429:9
+  --> $DIR/disallowed-positions.rs:425:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:434:9
+  --> $DIR/disallowed-positions.rs:430:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:438:9
+  --> $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:438:32
+  --> $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:447:9
+  --> $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:447:31
+  --> $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:453:9
+  --> $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:453:31
+  --> $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:459:9
+  --> $DIR/disallowed-positions.rs:455:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:476:22
+  --> $DIR/disallowed-positions.rs:472:22
    |
 LL |     let x = (true && let y = 1);
    |                      ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:481:20
+  --> $DIR/disallowed-positions.rs:477:20
    |
 LL |         ([1, 2, 3][let _ = ()])
    |                    ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:485:20
-   |
-LL |     #[cfg(FALSE)] (let 0 = 1);
-   |                    ^^^
-
-error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:97:16
+  --> $DIR/disallowed-positions.rs:99:16
    |
 LL |     use_expr!((let 0 = 1 && 0 == 0));
    |                ^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:101:16
+  --> $DIR/disallowed-positions.rs:103:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^
 
-error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:105:23
-   |
-LL |     use_expr!(true && let 0 = 1);
-   |                       ^^^
-
-error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:109:17
-   |
-LL |     noop_expr!((let 0 = 1));
-   |                 ^^^
-
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:27:9
+  --> $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:27:9
+  --> $DIR/disallowed-positions.rs:29:9
    |
 LL |     if (let 0 = 1) {}
    |         ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:31:11
+  --> $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:31:11
+  --> $DIR/disallowed-positions.rs:33:11
    |
 LL |     if (((let 0 = 1))) {}
    |           ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:35:9
+  --> $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:35:9
+  --> $DIR/disallowed-positions.rs:37:9
    |
 LL |     if (let 0 = 1) && true {}
    |         ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:39:17
+  --> $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:39:17
+  --> $DIR/disallowed-positions.rs:41:17
    |
 LL |     if true && (let 0 = 1) {}
    |                 ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:43:9
+  --> $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:43:9
+  --> $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:43:24
+  --> $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:43:24
+  --> $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:49:35
+  --> $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:49:35
+  --> $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:49:48
+  --> $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:49:35
+  --> $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:49:61
+  --> $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:49:35
+  --> $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:59:12
+  --> $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:59:12
+  --> $DIR/disallowed-positions.rs:61:12
    |
 LL |     while (let 0 = 1) {}
    |            ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:63:14
+  --> $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:63:14
+  --> $DIR/disallowed-positions.rs:65:14
    |
 LL |     while (((let 0 = 1))) {}
    |              ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:67:12
+  --> $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:67:12
+  --> $DIR/disallowed-positions.rs:69:12
    |
 LL |     while (let 0 = 1) && true {}
    |            ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:71:20
+  --> $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:71:20
+  --> $DIR/disallowed-positions.rs:73:20
    |
 LL |     while true && (let 0 = 1) {}
    |                    ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:75:12
+  --> $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:75:12
+  --> $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:75:27
+  --> $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:75:27
+  --> $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:81:38
+  --> $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:81:38
+  --> $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:81:51
+  --> $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:81:38
+  --> $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:81:64
+  --> $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:81:38
+  --> $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:97:16
+  --> $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:97:16
+  --> $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:97:16
+  --> $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:97:16
+  --> $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:101:16
+  --> $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:101:16
+  --> $DIR/disallowed-positions.rs:103:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:101:16
+  --> $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:101:16
+  --> $DIR/disallowed-positions.rs:103:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:114:9
+  --> $DIR/disallowed-positions.rs:110:9
    |
 LL |     if &let 0 = 0 {}
    |         ^^^^^^^^^
@@ -808,7 +790,7 @@ 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:119:9
+  --> $DIR/disallowed-positions.rs:115:9
    |
 LL |     if !let 0 = 0 {}
    |         ^^^^^^^^^
@@ -816,7 +798,7 @@ 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
+  --> $DIR/disallowed-positions.rs:118:9
    |
 LL |     if *let 0 = 0 {}
    |         ^^^^^^^^^
@@ -824,7 +806,7 @@ 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:126:9
+  --> $DIR/disallowed-positions.rs:122:9
    |
 LL |     if -let 0 = 0 {}
    |         ^^^^^^^^^
@@ -832,72 +814,72 @@ 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:136:9
+  --> $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:136:9
+  --> $DIR/disallowed-positions.rs:132:9
    |
 LL |     if (let 0 = 0)? {}
    |         ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:142:16
+  --> $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:142:13
+  --> $DIR/disallowed-positions.rs:138:13
    |
 LL |     if true || let 0 = 0 {}
    |             ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:145:17
+  --> $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:145:14
+  --> $DIR/disallowed-positions.rs:141:14
    |
 LL |     if (true || let 0 = 0) {}
    |              ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:148:25
+  --> $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:148:22
+  --> $DIR/disallowed-positions.rs:144:22
    |
 LL |     if true && (true || let 0 = 0) {}
    |                      ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:151:25
+  --> $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:151:17
+  --> $DIR/disallowed-positions.rs:147:17
    |
 LL |     if true || (true && let 0 = 0) {}
    |                 ^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:156:12
+  --> $DIR/disallowed-positions.rs:152:12
    |
 LL |     if x = let 0 = 0 {}
    |            ^^^^^^^^^
@@ -905,46 +887,46 @@ 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:161:15
+  --> $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:161:15
+  --> $DIR/disallowed-positions.rs:157:15
    |
 LL |     if true..(let 0 = 0) {}
    |               ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:165:11
+  --> $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:165:11
+  --> $DIR/disallowed-positions.rs:161:11
    |
 LL |     if ..(let 0 = 0) {}
    |           ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:169:9
+  --> $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:169:9
+  --> $DIR/disallowed-positions.rs:165:9
    |
 LL |     if (let 0 = 0).. {}
    |         ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:175:8
+  --> $DIR/disallowed-positions.rs:171:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -952,7 +934,7 @@ 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:179:8
+  --> $DIR/disallowed-positions.rs:175:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -960,7 +942,7 @@ 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:186:8
+  --> $DIR/disallowed-positions.rs:182:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -968,7 +950,7 @@ 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:194:8
+  --> $DIR/disallowed-positions.rs:190:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -976,7 +958,7 @@ 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:200:19
+  --> $DIR/disallowed-positions.rs:196:19
    |
 LL |     if let true = let true = true {}
    |                   ^^^^^^^^^^^^^^^
@@ -984,7 +966,7 @@ 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:206:12
+  --> $DIR/disallowed-positions.rs:202:12
    |
 LL |     while &let 0 = 0 {}
    |            ^^^^^^^^^
@@ -992,7 +974,7 @@ 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:211:12
+  --> $DIR/disallowed-positions.rs:207:12
    |
 LL |     while !let 0 = 0 {}
    |            ^^^^^^^^^
@@ -1000,7 +982,7 @@ 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
+  --> $DIR/disallowed-positions.rs:210:12
    |
 LL |     while *let 0 = 0 {}
    |            ^^^^^^^^^
@@ -1008,7 +990,7 @@ 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:218:12
+  --> $DIR/disallowed-positions.rs:214:12
    |
 LL |     while -let 0 = 0 {}
    |            ^^^^^^^^^
@@ -1016,72 +998,72 @@ 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:228:12
+  --> $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:228:12
+  --> $DIR/disallowed-positions.rs:224:12
    |
 LL |     while (let 0 = 0)? {}
    |            ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:234:19
+  --> $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:234:16
+  --> $DIR/disallowed-positions.rs:230:16
    |
 LL |     while true || let 0 = 0 {}
    |                ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:237:20
+  --> $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:237:17
+  --> $DIR/disallowed-positions.rs:233:17
    |
 LL |     while (true || let 0 = 0) {}
    |                 ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:240:28
+  --> $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:240:25
+  --> $DIR/disallowed-positions.rs:236:25
    |
 LL |     while true && (true || let 0 = 0) {}
    |                         ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:243:28
+  --> $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:243:20
+  --> $DIR/disallowed-positions.rs:239:20
    |
 LL |     while true || (true && let 0 = 0) {}
    |                    ^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:248:15
+  --> $DIR/disallowed-positions.rs:244:15
    |
 LL |     while x = let 0 = 0 {}
    |               ^^^^^^^^^
@@ -1089,46 +1071,46 @@ 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:253:18
+  --> $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:253:18
+  --> $DIR/disallowed-positions.rs:249:18
    |
 LL |     while true..(let 0 = 0) {}
    |                  ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:257:14
+  --> $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:257:14
+  --> $DIR/disallowed-positions.rs:253:14
    |
 LL |     while ..(let 0 = 0) {}
    |              ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:261:12
+  --> $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:261:12
+  --> $DIR/disallowed-positions.rs:257:12
    |
 LL |     while (let 0 = 0).. {}
    |            ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:267:11
+  --> $DIR/disallowed-positions.rs:263:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1136,7 +1118,7 @@ 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:271:11
+  --> $DIR/disallowed-positions.rs:267:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1144,7 +1126,7 @@ 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:278:11
+  --> $DIR/disallowed-positions.rs:274:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1152,7 +1134,7 @@ 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:286:11
+  --> $DIR/disallowed-positions.rs:282:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1160,7 +1142,7 @@ 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:292:22
+  --> $DIR/disallowed-positions.rs:288:22
    |
 LL |     while let true = let true = true {}
    |                      ^^^^^^^^^^^^^^^
@@ -1168,7 +1150,7 @@ 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:308:6
+  --> $DIR/disallowed-positions.rs:304:6
    |
 LL |     &let 0 = 0;
    |      ^^^^^^^^^
@@ -1176,7 +1158,7 @@ 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:312:6
+  --> $DIR/disallowed-positions.rs:308:6
    |
 LL |     !let 0 = 0;
    |      ^^^^^^^^^
@@ -1184,7 +1166,7 @@ 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
+  --> $DIR/disallowed-positions.rs:311:6
    |
 LL |     *let 0 = 0;
    |      ^^^^^^^^^
@@ -1192,7 +1174,7 @@ 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:319:6
+  --> $DIR/disallowed-positions.rs:315:6
    |
 LL |     -let 0 = 0;
    |      ^^^^^^^^^
@@ -1200,59 +1182,59 @@ 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:329:6
+  --> $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:329:6
+  --> $DIR/disallowed-positions.rs:325:6
    |
 LL |     (let 0 = 0)?;
    |      ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:335:13
+  --> $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:335:10
+  --> $DIR/disallowed-positions.rs:331:10
    |
 LL |     true || let 0 = 0;
    |          ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:338:14
+  --> $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:338:11
+  --> $DIR/disallowed-positions.rs:334:11
    |
 LL |     (true || let 0 = 0);
    |           ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:341:22
+  --> $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:341:19
+  --> $DIR/disallowed-positions.rs:337:19
    |
 LL |     true && (true || let 0 = 0);
    |                   ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:346:9
+  --> $DIR/disallowed-positions.rs:342:9
    |
 LL |     x = let 0 = 0;
    |         ^^^^^^^^^
@@ -1260,46 +1242,46 @@ 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:350:12
+  --> $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:350:12
+  --> $DIR/disallowed-positions.rs:346:12
    |
 LL |     true..(let 0 = 0);
    |            ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:353:8
+  --> $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:353:8
+  --> $DIR/disallowed-positions.rs:349:8
    |
 LL |     ..(let 0 = 0);
    |        ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:356:6
+  --> $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:356:6
+  --> $DIR/disallowed-positions.rs:352:6
    |
 LL |     (let 0 = 0)..;
    |      ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:360:6
+  --> $DIR/disallowed-positions.rs:356:6
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1307,20 +1289,20 @@ 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:365:6
+  --> $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:365:6
+  --> $DIR/disallowed-positions.rs:361:6
    |
 LL |     (let true = let true = true);
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:383:6
+  --> $DIR/disallowed-positions.rs:379:6
    |
 LL |     &let 0 = 0
    |      ^^^^^^^^^
@@ -1328,7 +1310,7 @@ 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:395:17
+  --> $DIR/disallowed-positions.rs:391:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -1336,7 +1318,7 @@ 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:401:17
+  --> $DIR/disallowed-positions.rs:397:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -1344,7 +1326,7 @@ 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:407:17
+  --> $DIR/disallowed-positions.rs:403:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -1352,7 +1334,7 @@ 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:419:17
+  --> $DIR/disallowed-positions.rs:415:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -1360,124 +1342,124 @@ 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:429:9
+  --> $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:429:9
+  --> $DIR/disallowed-positions.rs:425:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:434:9
+  --> $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:434:9
+  --> $DIR/disallowed-positions.rs:430:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:438:9
+  --> $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:438:9
+  --> $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:438:32
+  --> $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:438:32
+  --> $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:447:9
+  --> $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:447:9
+  --> $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:447:31
+  --> $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:447:31
+  --> $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:453:9
+  --> $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:453:9
+  --> $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:453:31
+  --> $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:453:31
+  --> $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:459:9
+  --> $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:459:9
+  --> $DIR/disallowed-positions.rs:455:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:114:8
+  --> $DIR/disallowed-positions.rs:110:8
    |
 LL |     if &let 0 = 0 {}
    |        ^^^^^^^^^^ expected `bool`, found `&bool`
@@ -1489,19 +1471,19 @@ LL +     if let 0 = 0 {}
    |
 
 error[E0614]: type `bool` cannot be dereferenced
-  --> $DIR/disallowed-positions.rs:122:8
+  --> $DIR/disallowed-positions.rs:118:8
    |
 LL |     if *let 0 = 0 {}
    |        ^^^^^^^^^^
 
 error[E0600]: cannot apply unary operator `-` to type `bool`
-  --> $DIR/disallowed-positions.rs:126:8
+  --> $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:136:8
+  --> $DIR/disallowed-positions.rs:132:8
    |
 LL |     if (let 0 = 0)? {}
    |        ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
@@ -1509,7 +1491,7 @@ LL |     if (let 0 = 0)? {}
    = 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:136:19
+  --> $DIR/disallowed-positions.rs:132:19
    |
 LL | / fn nested_within_if_expr() {
 LL | |     if &let 0 = 0 {}
@@ -1526,7 +1508,7 @@ LL | | }
    = help: the trait `FromResidual<_>` is not implemented for `()`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:156:8
+  --> $DIR/disallowed-positions.rs:152:8
    |
 LL |     if x = let 0 = 0 {}
    |        ^^^^^^^^^^^^^ expected `bool`, found `()`
@@ -1537,7 +1519,7 @@ LL |     if x == let 0 = 0 {}
    |          ~~
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:161:8
+  --> $DIR/disallowed-positions.rs:157:8
    |
 LL |     if true..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1546,7 +1528,7 @@ LL |     if true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:165:8
+  --> $DIR/disallowed-positions.rs:161:8
    |
 LL |     if ..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo`
@@ -1555,7 +1537,7 @@ LL |     if ..(let 0 = 0) {}
             found struct `RangeTo<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:169:8
+  --> $DIR/disallowed-positions.rs:165:8
    |
 LL |     if (let 0 = 0).. {}
    |        ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom`
@@ -1564,7 +1546,7 @@ LL |     if (let 0 = 0).. {}
             found struct `RangeFrom<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:175:12
+  --> $DIR/disallowed-positions.rs:171:12
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1575,7 +1557,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:175:8
+  --> $DIR/disallowed-positions.rs:171:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1584,7 +1566,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:179:12
+  --> $DIR/disallowed-positions.rs:175:12
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1595,7 +1577,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:179:8
+  --> $DIR/disallowed-positions.rs:175:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1604,7 +1586,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:186:12
+  --> $DIR/disallowed-positions.rs:182:12
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -1615,20 +1597,20 @@ LL |     if let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:186:41
+  --> $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:186:41: 186:43]`
+           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:186:8
+  --> $DIR/disallowed-positions.rs:182:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1637,7 +1619,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:194:12
+  --> $DIR/disallowed-positions.rs:190:12
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -1648,7 +1630,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:194:44
+  --> $DIR/disallowed-positions.rs:190:44
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |                                            ^^^^^^^ expected `bool`, found `&&bool`
@@ -1660,7 +1642,7 @@ LL +     if let Range { start: true, end } = t..false {}
    |
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:194:8
+  --> $DIR/disallowed-positions.rs:190:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1669,7 +1651,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<bool>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:132:20
+  --> $DIR/disallowed-positions.rs:128:20
    |
 LL |         if let 0 = 0? {}
    |                    ^^ the `?` operator cannot be applied to type `{integer}`
@@ -1677,7 +1659,7 @@ LL |         if let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:206:11
+  --> $DIR/disallowed-positions.rs:202:11
    |
 LL |     while &let 0 = 0 {}
    |           ^^^^^^^^^^ expected `bool`, found `&bool`
@@ -1689,19 +1671,19 @@ LL +     while let 0 = 0 {}
    |
 
 error[E0614]: type `bool` cannot be dereferenced
-  --> $DIR/disallowed-positions.rs:214:11
+  --> $DIR/disallowed-positions.rs:210:11
    |
 LL |     while *let 0 = 0 {}
    |           ^^^^^^^^^^
 
 error[E0600]: cannot apply unary operator `-` to type `bool`
-  --> $DIR/disallowed-positions.rs:218:11
+  --> $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:228:11
+  --> $DIR/disallowed-positions.rs:224:11
    |
 LL |     while (let 0 = 0)? {}
    |           ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
@@ -1709,7 +1691,7 @@ LL |     while (let 0 = 0)? {}
    = 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:228:22
+  --> $DIR/disallowed-positions.rs:224:22
    |
 LL | / fn nested_within_while_expr() {
 LL | |     while &let 0 = 0 {}
@@ -1726,7 +1708,7 @@ LL | | }
    = help: the trait `FromResidual<_>` is not implemented for `()`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:248:11
+  --> $DIR/disallowed-positions.rs:244:11
    |
 LL |     while x = let 0 = 0 {}
    |           ^^^^^^^^^^^^^ expected `bool`, found `()`
@@ -1737,7 +1719,7 @@ LL |     while x == let 0 = 0 {}
    |             ~~
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:253:11
+  --> $DIR/disallowed-positions.rs:249:11
    |
 LL |     while true..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1746,7 +1728,7 @@ LL |     while true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:257:11
+  --> $DIR/disallowed-positions.rs:253:11
    |
 LL |     while ..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo`
@@ -1755,7 +1737,7 @@ LL |     while ..(let 0 = 0) {}
             found struct `RangeTo<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:261:11
+  --> $DIR/disallowed-positions.rs:257:11
    |
 LL |     while (let 0 = 0).. {}
    |           ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom`
@@ -1764,7 +1746,7 @@ LL |     while (let 0 = 0).. {}
             found struct `RangeFrom<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:267:15
+  --> $DIR/disallowed-positions.rs:263:15
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1775,7 +1757,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:267:11
+  --> $DIR/disallowed-positions.rs:263:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1784,7 +1766,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:271:15
+  --> $DIR/disallowed-positions.rs:267:15
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1795,7 +1777,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:271:11
+  --> $DIR/disallowed-positions.rs:267:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1804,7 +1786,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:278:15
+  --> $DIR/disallowed-positions.rs:274:15
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -1815,20 +1797,20 @@ LL |     while let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:278:44
+  --> $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:278:44: 278:46]`
+           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:278:11
+  --> $DIR/disallowed-positions.rs:274:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1837,7 +1819,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:286:15
+  --> $DIR/disallowed-positions.rs:282:15
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -1848,7 +1830,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:286:47
+  --> $DIR/disallowed-positions.rs:282:47
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |                                               ^^^^^^^ expected `bool`, found `&&bool`
@@ -1860,7 +1842,7 @@ LL +     while let Range { start: true, end } = t..false {}
    |
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:286:11
+  --> $DIR/disallowed-positions.rs:282:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1869,7 +1851,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<bool>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:224:23
+  --> $DIR/disallowed-positions.rs:220:23
    |
 LL |         while let 0 = 0? {}
    |                       ^^ the `?` operator cannot be applied to type `{integer}`
@@ -1877,19 +1859,19 @@ LL |         while let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0614]: type `bool` cannot be dereferenced
-  --> $DIR/disallowed-positions.rs:315:5
+  --> $DIR/disallowed-positions.rs:311:5
    |
 LL |     *let 0 = 0;
    |     ^^^^^^^^^^
 
 error[E0600]: cannot apply unary operator `-` to type `bool`
-  --> $DIR/disallowed-positions.rs:319:5
+  --> $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:329:5
+  --> $DIR/disallowed-positions.rs:325:5
    |
 LL |     (let 0 = 0)?;
    |     ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
@@ -1897,7 +1879,7 @@ LL |     (let 0 = 0)?;
    = 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:329:16
+  --> $DIR/disallowed-positions.rs:325:16
    |
 LL | / fn outside_if_and_while_expr() {
 LL | |     &let 0 = 0;
@@ -1914,7 +1896,7 @@ LL | | }
    = help: the trait `FromResidual<_>` is not implemented for `()`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:360:10
+  --> $DIR/disallowed-positions.rs:356:10
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1925,7 +1907,7 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:383:5
+  --> $DIR/disallowed-positions.rs:379:5
    |
 LL | fn outside_if_and_while_expr() {
    |                                - help: try adding a return type: `-> &bool`
@@ -1934,14 +1916,14 @@ LL |     &let 0 = 0
    |     ^^^^^^^^^^ expected `()`, found `&bool`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:325:17
+  --> $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 218 previous errors
+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/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
index deef4240d4d..12befc637c7 100644
--- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
@@ -1,4 +1,4 @@
-#![feature(let_else)]
+#![feature(let_chains, let_else)]
 
 fn main() {
     let opt = Some(1i32);
diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs b/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs
new file mode 100644
index 00000000000..2b407ef510c
--- /dev/null
+++ b/src/test/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/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr
new file mode 100644
index 00000000000..feea1c254d8
--- /dev/null
+++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr
@@ -0,0 +1,114 @@
+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
+
+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/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs
index 7bc6d43a727..a942d1f4caf 100644
--- a/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs
@@ -1,3 +1,5 @@
+#![feature(let_chains)]
+
 fn main() {
     let _opt = Some(1i32);
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr
index d1552a0b2d5..d1ce83c7233 100644
--- a/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr
@@ -1,35 +1,35 @@
 error: expected expression, found `let` statement
-  --> $DIR/invalid-let-in-a-valid-let-context.rs:6:19
+  --> $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:11:47
+  --> $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:11:57
+  --> $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:21:23
+  --> $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:30:47
+  --> $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:38:21
+  --> $DIR/invalid-let-in-a-valid-let-context.rs:40:21
    |
 LL |             let x = let y = 1;
    |                     ^^^
diff --git a/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.rs b/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.rs
index 1ef4bc56e52..3d1626e8ffb 100644
--- a/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.rs
@@ -1,7 +1,7 @@
 // revisions: allowed disallowed
 //[allowed] check-pass
 
-#![feature(if_let_guard)]
+#![feature(if_let_guard, let_chains)]
 #![cfg_attr(allowed, allow(irrefutable_let_patterns))]
 #![cfg_attr(disallowed, deny(irrefutable_let_patterns))]
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/issue-90722.rs b/src/test/ui/rfc-2497-if-let-chains/issue-90722.rs
index 34302ba96d3..6b7d8835650 100644
--- a/src/test/ui/rfc-2497-if-let-chains/issue-90722.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/issue-90722.rs
@@ -1,5 +1,7 @@
 // check-pass
 
+#![feature(let_chains)]
+
 fn main() {
     let x = Some(vec!["test"]);
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/issue-92145.rs b/src/test/ui/rfc-2497-if-let-chains/issue-92145.rs
index 6938062fa35..7c7e31f4db4 100644
--- a/src/test/ui/rfc-2497-if-let-chains/issue-92145.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/issue-92145.rs
@@ -1,5 +1,7 @@
 // check-pass
 
+#![feature(let_chains)]
+
 fn main() {
     let opt = Some("foo bar");
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/issue-93150.rs b/src/test/ui/rfc-2497-if-let-chains/issue-93150.rs
index f6de37867d8..f90b9ab0d40 100644
--- a/src/test/ui/rfc-2497-if-let-chains/issue-93150.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/issue-93150.rs
@@ -2,6 +2,7 @@ fn main() {
     match true {
         _ if let true = true && true => {}
         //~^ ERROR `if let` guards are
+        //~| ERROR `let` expressions in this
         _ => {}
     }
 }
diff --git a/src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr b/src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr
index 0d620df96f6..b25f299a219 100644
--- a/src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr
@@ -8,6 +8,15 @@ LL |         _ if let true = true && true => {}
    = 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: aborting due to previous error
+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/src/test/ui/rfc-2497-if-let-chains/then-else-blocks.rs b/src/test/ui/rfc-2497-if-let-chains/then-else-blocks.rs
index beaca33d563..e061174f667 100644
--- a/src/test/ui/rfc-2497-if-let-chains/then-else-blocks.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/then-else-blocks.rs
@@ -1,6 +1,6 @@
 // run-pass
 
-#![feature(if_let_guard)]
+#![feature(if_let_guard, let_chains)]
 
 fn check_if_let(opt: Option<Option<Option<i32>>>, value: i32) -> bool {
     if let Some(first) = opt
diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs
index 8a6bd1cbdf5..82574a8e64b 100644
--- a/src/tools/clippy/clippy_dev/src/lib.rs
+++ b/src/tools/clippy/clippy_dev/src/lib.rs
@@ -1,3 +1,4 @@
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(once_cell)]
 #![feature(rustc_private)]
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index e6a405f8170..ec5c73c1357 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -4,6 +4,7 @@
 #![feature(control_flow_enum)]
 #![feature(drain_filter)]
 #![feature(iter_intersperse)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(lint_reasons)]
 #![feature(never_type)]
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index f716f009ff3..313f1f1d9a6 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -2,6 +2,7 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(let_else)]
+#![feature(let_chains)]
 #![feature(lint_reasons)]
 #![feature(once_cell)]
 #![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui/needless_late_init.fixed b/src/tools/clippy/tests/ui/needless_late_init.fixed
index 4c98e1827bd..fee8e3030b8 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.fixed
+++ b/src/tools/clippy/tests/ui/needless_late_init.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![feature(let_chains)]
 #![allow(
     unused,
     clippy::assign_op_pattern,
diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs
index 25e1e0214fb..402d9f9ef7f 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.rs
+++ b/src/tools/clippy/tests/ui/needless_late_init.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![feature(let_chains)]
 #![allow(
     unused,
     clippy::assign_op_pattern,
diff --git a/src/tools/clippy/tests/ui/needless_late_init.stderr b/src/tools/clippy/tests/ui/needless_late_init.stderr
index 97f0f7019a9..313cdbbeba1 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.stderr
+++ b/src/tools/clippy/tests/ui/needless_late_init.stderr
@@ -1,5 +1,5 @@
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:22:5
+  --> $DIR/needless_late_init.rs:23:5
    |
 LL |     let a;
    |     ^^^^^^ created here
@@ -13,7 +13,7 @@ LL |     let a = "zero";
    |     ~~~~~
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:25:5
+  --> $DIR/needless_late_init.rs:26:5
    |
 LL |     let b;
    |     ^^^^^^ created here
@@ -27,7 +27,7 @@ LL |     let b = 1;
    |     ~~~~~
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:26:5
+  --> $DIR/needless_late_init.rs:27:5
    |
 LL |     let c;
    |     ^^^^^^ created here
@@ -41,7 +41,7 @@ LL |     let c = 2;
    |     ~~~~~
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:30:5
+  --> $DIR/needless_late_init.rs:31:5
    |
 LL |     let d: usize;
    |     ^^^^^^^^^^^^^ created here
@@ -54,7 +54,7 @@ LL |     let d: usize = 1;
    |     ~~~~~~~~~~~~
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:33:5
+  --> $DIR/needless_late_init.rs:34:5
    |
 LL |     let e;
    |     ^^^^^^ created here
@@ -67,7 +67,7 @@ LL |     let e = format!("{}", d);
    |     ~~~~~
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:38:5
+  --> $DIR/needless_late_init.rs:39:5
    |
 LL |     let a;
    |     ^^^^^^
@@ -88,7 +88,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:47:5
+  --> $DIR/needless_late_init.rs:48:5
    |
 LL |     let b;
    |     ^^^^^^
@@ -109,7 +109,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:54:5
+  --> $DIR/needless_late_init.rs:55:5
    |
 LL |     let d;
    |     ^^^^^^
@@ -130,7 +130,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:62:5
+  --> $DIR/needless_late_init.rs:63:5
    |
 LL |     let e;
    |     ^^^^^^
@@ -151,7 +151,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:69:5
+  --> $DIR/needless_late_init.rs:70:5
    |
 LL |     let f;
    |     ^^^^^^
@@ -167,7 +167,7 @@ LL +         1 => "three",
    |
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:75:5
+  --> $DIR/needless_late_init.rs:76:5
    |
 LL |     let g: usize;
    |     ^^^^^^^^^^^^^
@@ -187,7 +187,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:83:5
+  --> $DIR/needless_late_init.rs:84:5
    |
 LL |     let x;
    |     ^^^^^^ created here
@@ -201,7 +201,7 @@ LL |     let x = 1;
    |     ~~~~~
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:87:5
+  --> $DIR/needless_late_init.rs:88:5
    |
 LL |     let x;
    |     ^^^^^^ created here
@@ -215,7 +215,7 @@ LL |     let x = SignificantDrop;
    |     ~~~~~
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:91:5
+  --> $DIR/needless_late_init.rs:92:5
    |
 LL |     let x;
    |     ^^^^^^ created here
@@ -229,7 +229,7 @@ LL |     let x = SignificantDrop;
    |     ~~~~~
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:110:5
+  --> $DIR/needless_late_init.rs:111:5
    |
 LL |     let a;
    |     ^^^^^^
@@ -250,7 +250,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:127:5
+  --> $DIR/needless_late_init.rs:128:5
    |
 LL |     let a;
    |     ^^^^^^