about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs1
-rw-r--r--compiler/rustc_const_eval/messages.ftl4
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs89
-rw-r--r--compiler/rustc_const_eval/src/check_consts/ops.rs53
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs5
-rw-r--r--compiler/rustc_const_eval/src/errors.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs132
-rw-r--r--compiler/rustc_const_eval/src/interpret/mod.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs91
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs86
-rw-r--r--compiler/rustc_session/src/parse.rs1
-rw-r--r--compiler/rustc_session/src/session.rs1
-rw-r--r--src/doc/unstable-book/src/compiler-flags/wasm-c-abi.md4
-rw-r--r--src/doc/unstable-book/src/language-features/asm-experimental-arch.md21
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs18
-rw-r--r--src/tools/miri/src/borrow_tracker/mod.rs2
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs4
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs4
-rw-r--r--src/tools/miri/src/machine.rs8
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs4
-rw-r--r--tests/assembly/asm/s390x-types.rs2
-rw-r--r--tests/codegen/asm/s390x-clobbers.rs2
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.rs340
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.feature.stderr (renamed from tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.stderr)446
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.no_feature.stderr1239
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nofeature.stderr (renamed from tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.stderr)368
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nothing.stderr990
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs111
-rw-r--r--tests/ui/traits/const-traits/cross-crate.rs4
-rw-r--r--tests/ui/traits/const-traits/cross-crate.stock.stderr31
-rw-r--r--tests/ui/traits/const-traits/cross-crate.stocknc.stderr58
-rw-r--r--tests/ui/traits/const-traits/staged-api-user-crate.rs3
-rw-r--r--tests/ui/traits/const-traits/staged-api-user-crate.stderr27
-rw-r--r--tests/ui/traits/const-traits/staged-api.rs50
-rw-r--r--tests/ui/traits/const-traits/staged-api.stable.stderr89
-rw-r--r--tests/ui/traits/const-traits/staged-api.stderr139
-rw-r--r--tests/ui/traits/const-traits/staged-api.unstable.stderr108
-rw-r--r--triagebot.toml1
38 files changed, 3312 insertions, 1236 deletions
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 6585a7de245..3acca94a54b 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -48,6 +48,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     | asm::InlineAsmArch::RiscV32
                     | asm::InlineAsmArch::RiscV64
                     | asm::InlineAsmArch::LoongArch64
+                    | asm::InlineAsmArch::S390x
             );
             if !is_stable && !self.tcx.features().asm_experimental_arch() {
                 feature_err(
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 826e34930ea..15027ae0c18 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -25,6 +25,10 @@ const_eval_closure_fndef_not_const =
     function defined here, but it is not `const`
 const_eval_closure_non_const =
     cannot call non-const closure in {const_eval_const_context}s
+
+const_eval_conditionally_const_call =
+    cannot call conditionally-const {$def_descr} `{$def_path_str}` in {const_eval_const_context}s
+
 const_eval_consider_dereferencing =
     consider dereferencing here
 
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index aea3d5bd3e7..8cd0ecb3e4e 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -15,7 +15,7 @@ use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::*;
 use rustc_middle::span_bug;
 use rustc_middle::ty::adjustment::PointerCoercion;
-use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt};
+use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 use rustc_mir_dataflow::Analysis;
 use rustc_mir_dataflow::impls::MaybeStorageLive;
 use rustc_mir_dataflow::storage::always_storage_live_locals;
@@ -361,31 +361,21 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
         !is_transient
     }
 
+    /// Returns whether there are const-conditions.
     fn revalidate_conditional_constness(
         &mut self,
         callee: DefId,
         callee_args: ty::GenericArgsRef<'tcx>,
-        call_source: CallSource,
         call_span: Span,
-    ) {
+    ) -> bool {
         let tcx = self.tcx;
         if !tcx.is_conditionally_const(callee) {
-            return;
+            return false;
         }
 
         let const_conditions = tcx.const_conditions(callee).instantiate(tcx, callee_args);
-        // If there are any const conditions on this fn and `const_trait_impl`
-        // is not enabled, simply bail. We shouldn't be able to call conditionally
-        // const functions on stable.
-        if !const_conditions.is_empty() && !tcx.features().const_trait_impl() {
-            self.check_op(ops::FnCallNonConst {
-                callee,
-                args: callee_args,
-                span: call_span,
-                call_source,
-                feature: Some(sym::const_trait_impl),
-            });
-            return;
+        if const_conditions.is_empty() {
+            return false;
         }
 
         let infcx = tcx.infer_ctxt().build(self.body.typing_mode(tcx));
@@ -421,6 +411,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
             tcx.dcx()
                 .span_delayed_bug(call_span, "this should have reported a ~const error in HIR");
         }
+
+        true
     }
 }
 
@@ -627,11 +619,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     _ => unreachable!(),
                 };
 
-                let ConstCx { tcx, body, param_env, .. } = *self.ccx;
+                let ConstCx { tcx, body, .. } = *self.ccx;
 
                 let fn_ty = func.ty(body, tcx);
 
-                let (mut callee, mut fn_args) = match *fn_ty.kind() {
+                let (callee, fn_args) = match *fn_ty.kind() {
                     ty::FnDef(def_id, fn_args) => (def_id, fn_args),
 
                     ty::FnPtr(..) => {
@@ -645,57 +637,38 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     }
                 };
 
-                self.revalidate_conditional_constness(callee, fn_args, call_source, *fn_span);
+                let has_const_conditions =
+                    self.revalidate_conditional_constness(callee, fn_args, *fn_span);
 
-                let mut is_trait = false;
                 // Attempting to call a trait method?
                 if let Some(trait_did) = tcx.trait_of_item(callee) {
-                    trace!("attempting to call a trait method");
+                    // We can't determine the actual callee here, so we have to do different checks
+                    // than usual.
 
+                    trace!("attempting to call a trait method");
                     let trait_is_const = tcx.is_const_trait(trait_did);
-                    // trait method calls are only permitted when `effects` is enabled.
-                    // typeck ensures the conditions for calling a const trait method are met,
-                    // so we only error if the trait isn't const. We try to resolve the trait
-                    // into the concrete method, and uses that for const stability checks.
-                    // FIXME(const_trait_impl) we might consider moving const stability checks
-                    // to typeck as well.
-                    if tcx.features().const_trait_impl() && trait_is_const {
-                        // This skips the check below that ensures we only call `const fn`.
-                        is_trait = true;
-
-                        if let Ok(Some(instance)) =
-                            Instance::try_resolve(tcx, param_env, callee, fn_args)
-                            && let InstanceKind::Item(def) = instance.def
-                        {
-                            // Resolve a trait method call to its concrete implementation, which may be in a
-                            // `const` trait impl. This is only used for the const stability check below, since
-                            // we want to look at the concrete impl's stability.
-                            fn_args = instance.args;
-                            callee = def;
-                        }
+
+                    if trait_is_const {
+                        // Trait calls are always conditionally-const.
+                        self.check_op(ops::ConditionallyConstCall { callee, args: fn_args });
+                        // FIXME(const_trait_impl): do a more fine-grained check whether this
+                        // particular trait can be const-stably called.
                     } else {
-                        // if the trait is const but the user has not enabled the feature(s),
-                        // suggest them.
-                        let feature = if trait_is_const {
-                            Some(if tcx.features().const_trait_impl() {
-                                sym::effects
-                            } else {
-                                sym::const_trait_impl
-                            })
-                        } else {
-                            None
-                        };
+                        // Not even a const trait.
                         self.check_op(ops::FnCallNonConst {
                             callee,
                             args: fn_args,
                             span: *fn_span,
                             call_source,
-                            feature,
                         });
-                        // If we allowed this, we're in miri-unleashed mode, so we might
-                        // as well skip the remaining checks.
-                        return;
                     }
+                    // That's all we can check here.
+                    return;
+                }
+
+                // Even if we know the callee, ensure we can use conditionally-const calls.
+                if has_const_conditions {
+                    self.check_op(ops::ConditionallyConstCall { callee, args: fn_args });
                 }
 
                 // At this point, we are calling a function, `callee`, whose `DefId` is known...
@@ -783,14 +756,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     return;
                 }
 
-                // Trait functions are not `const fn` so we have to skip them here.
-                if !tcx.is_const_fn(callee) && !is_trait {
+                if !tcx.is_const_fn(callee) {
                     self.check_op(ops::FnCallNonConst {
                         callee,
                         args: fn_args,
                         span: *fn_span,
                         call_source,
-                        feature: None,
                     });
                     // If we allowed this, we're in miri-unleashed mode, so we might
                     // as well skip the remaining checks.
diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index 2931159842f..036ca763280 100644
--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
@@ -70,6 +70,37 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
     }
 }
 
+/// A call to a function that is in a trait, or has trait bounds that make it conditionally-const.
+#[derive(Debug)]
+pub(crate) struct ConditionallyConstCall<'tcx> {
+    pub callee: DefId,
+    pub args: GenericArgsRef<'tcx>,
+}
+
+impl<'tcx> NonConstOp<'tcx> for ConditionallyConstCall<'tcx> {
+    fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
+        // We use the `const_trait_impl` gate for all conditionally-const calls.
+        Status::Unstable {
+            gate: sym::const_trait_impl,
+            safe_to_expose_on_stable: false,
+            // We don't want the "mark the callee as `#[rustc_const_stable_indirect]`" hint
+            is_function_call: false,
+        }
+    }
+
+    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
+        ccx.tcx.sess.create_feature_err(
+            errors::ConditionallyConstCall {
+                span,
+                def_path_str: ccx.tcx.def_path_str_with_args(self.callee, self.args),
+                def_descr: ccx.tcx.def_descr(self.callee),
+                kind: ccx.const_kind(),
+            },
+            sym::const_trait_impl,
+        )
+    }
+}
+
 /// A function call where the callee is not marked as `const`.
 #[derive(Debug, Clone, Copy)]
 pub(crate) struct FnCallNonConst<'tcx> {
@@ -77,7 +108,6 @@ pub(crate) struct FnCallNonConst<'tcx> {
     pub args: GenericArgsRef<'tcx>,
     pub span: Span,
     pub call_source: CallSource,
-    pub feature: Option<Symbol>,
 }
 
 impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
@@ -85,7 +115,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
     #[allow(rustc::diagnostic_outside_of_impl)]
     #[allow(rustc::untranslatable_diagnostic)]
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> {
-        let FnCallNonConst { callee, args, span, call_source, feature } = *self;
+        let FnCallNonConst { callee, args, span, call_source } = *self;
         let ConstCx { tcx, param_env, .. } = *ccx;
         let caller = ccx.def_id();
 
@@ -285,14 +315,6 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
             ccx.const_kind(),
         ));
 
-        if let Some(feature) = feature {
-            ccx.tcx.disabled_nightly_features(
-                &mut err,
-                Some(ccx.tcx.local_def_id_to_hir_id(caller)),
-                [(String::new(), feature)],
-            );
-        }
-
         if let ConstContext::Static(_) = ccx.const_kind() {
             err.note(fluent_generated::const_eval_lazy_lock);
         }
@@ -398,15 +420,8 @@ impl<'tcx> NonConstOp<'tcx> for Coroutine {
 
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
         let msg = format!("{:#}s are not allowed in {}s", self.0, ccx.const_kind());
-        if let hir::CoroutineKind::Desugared(
-            hir::CoroutineDesugaring::Async,
-            hir::CoroutineSource::Block,
-        ) = self.0
-        {
-            ccx.tcx.sess.create_feature_err(
-                errors::UnallowedOpInConstContext { span, msg },
-                sym::const_async_blocks,
-            )
+        if let Status::Unstable { gate, .. } = self.status_in_item(ccx) {
+            ccx.tcx.sess.create_feature_err(errors::UnallowedOpInConstContext { span, msg }, gate)
         } else {
             ccx.dcx().create_err(errors::UnallowedOpInConstContext { span, msg })
         }
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 81b9d73b952..a430d9dc797 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -472,8 +472,9 @@ fn report_validation_error<'tcx>(
     backtrace.print_backtrace();
 
     let bytes = ecx.print_alloc_bytes_for_diagnostics(alloc_id);
-    let (size, align, _) = ecx.get_alloc_info(alloc_id);
-    let raw_bytes = errors::RawBytesNote { size: size.bytes(), align: align.bytes(), bytes };
+    let info = ecx.get_alloc_info(alloc_id);
+    let raw_bytes =
+        errors::RawBytesNote { size: info.size.bytes(), align: info.align.bytes(), bytes };
 
     crate::const_eval::report(
         *ecx.tcx,
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 14e8bebbb18..604e5ed61a3 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -177,6 +177,16 @@ pub(crate) struct NonConstFmtMacroCall {
 }
 
 #[derive(Diagnostic)]
+#[diag(const_eval_conditionally_const_call)]
+pub(crate) struct ConditionallyConstCall {
+    #[primary_span]
+    pub span: Span,
+    pub def_path_str: String,
+    pub def_descr: &'static str,
+    pub kind: ConstContext,
+}
+
+#[derive(Diagnostic)]
 #[diag(const_eval_non_const_fn_call, code = E0015)]
 pub(crate) struct NonConstFnCall {
     #[primary_span]
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 1ad8ffa4b53..09635c96e57 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -14,10 +14,9 @@ use std::{fmt, mem, ptr};
 use rustc_abi::{Align, HasDataLayout, Size};
 use rustc_ast::Mutability;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
-use rustc_hir::def::DefKind;
 use rustc_middle::bug;
 use rustc_middle::mir::display_allocation;
-use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
 use tracing::{debug, instrument, trace};
 
 use super::{
@@ -72,6 +71,21 @@ pub enum AllocKind {
     Dead,
 }
 
+/// Metadata about an `AllocId`.
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct AllocInfo {
+    pub size: Size,
+    pub align: Align,
+    pub kind: AllocKind,
+    pub mutbl: Mutability,
+}
+
+impl AllocInfo {
+    fn new(size: Size, align: Align, kind: AllocKind, mutbl: Mutability) -> Self {
+        Self { size, align, kind, mutbl }
+    }
+}
+
 /// The value of a function pointer.
 #[derive(Debug, Copy, Clone)]
 pub enum FnVal<'tcx, Other> {
@@ -524,17 +538,22 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         match self.ptr_try_get_alloc_id(ptr, 0) {
             Err(addr) => is_offset_misaligned(addr, align),
             Ok((alloc_id, offset, _prov)) => {
-                let (_size, alloc_align, kind) = self.get_alloc_info(alloc_id);
-                if let Some(misalign) =
-                    M::alignment_check(self, alloc_id, alloc_align, kind, offset, align)
-                {
+                let alloc_info = self.get_alloc_info(alloc_id);
+                if let Some(misalign) = M::alignment_check(
+                    self,
+                    alloc_id,
+                    alloc_info.align,
+                    alloc_info.kind,
+                    offset,
+                    align,
+                ) {
                     Some(misalign)
                 } else if M::Provenance::OFFSET_IS_ADDR {
                     is_offset_misaligned(ptr.addr().bytes(), align)
                 } else {
                     // Check allocation alignment and offset alignment.
-                    if alloc_align.bytes() < align.bytes() {
-                        Some(Misalignment { has: alloc_align, required: align })
+                    if alloc_info.align.bytes() < align.bytes() {
+                        Some(Misalignment { has: alloc_info.align, required: align })
                     } else {
                         is_offset_misaligned(offset.bytes(), align)
                     }
@@ -818,82 +837,45 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
     /// Obtain the size and alignment of an allocation, even if that allocation has
     /// been deallocated.
-    pub fn get_alloc_info(&self, id: AllocId) -> (Size, Align, AllocKind) {
+    pub fn get_alloc_info(&self, id: AllocId) -> AllocInfo {
         // # Regular allocations
         // Don't use `self.get_raw` here as that will
         // a) cause cycles in case `id` refers to a static
         // b) duplicate a global's allocation in miri
         if let Some((_, alloc)) = self.memory.alloc_map.get(id) {
-            return (alloc.size(), alloc.align, AllocKind::LiveData);
+            return AllocInfo::new(
+                alloc.size(),
+                alloc.align,
+                AllocKind::LiveData,
+                alloc.mutability,
+            );
         }
 
         // # Function pointers
         // (both global from `alloc_map` and local from `extra_fn_ptr_map`)
         if self.get_fn_alloc(id).is_some() {
-            return (Size::ZERO, Align::ONE, AllocKind::Function);
+            return AllocInfo::new(Size::ZERO, Align::ONE, AllocKind::Function, Mutability::Not);
         }
 
-        // # Statics
-        // Can't do this in the match argument, we may get cycle errors since the lock would
-        // be held throughout the match.
-        match self.tcx.try_get_global_alloc(id) {
-            Some(GlobalAlloc::Static(def_id)) => {
-                // Thread-local statics do not have a constant address. They *must* be accessed via
-                // `ThreadLocalRef`; we can never have a pointer to them as a regular constant value.
-                assert!(!self.tcx.is_thread_local_static(def_id));
-
-                let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else {
-                    bug!("GlobalAlloc::Static is not a static")
-                };
-
-                let (size, align) = if nested {
-                    // Nested anonymous statics are untyped, so let's get their
-                    // size and alignment from the allocation itself. This always
-                    // succeeds, as the query is fed at DefId creation time, so no
-                    // evaluation actually occurs.
-                    let alloc = self.tcx.eval_static_initializer(def_id).unwrap();
-                    (alloc.0.size(), alloc.0.align)
-                } else {
-                    // Use size and align of the type for everything else. We need
-                    // to do that to
-                    // * avoid cycle errors in case of self-referential statics,
-                    // * be able to get information on extern statics.
-                    let ty = self
-                        .tcx
-                        .type_of(def_id)
-                        .no_bound_vars()
-                        .expect("statics should not have generic parameters");
-                    let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
-                    assert!(layout.is_sized());
-                    (layout.size, layout.align.abi)
-                };
-                (size, align, AllocKind::LiveData)
-            }
-            Some(GlobalAlloc::Memory(alloc)) => {
-                // Need to duplicate the logic here, because the global allocations have
-                // different associated types than the interpreter-local ones.
-                let alloc = alloc.inner();
-                (alloc.size(), alloc.align, AllocKind::LiveData)
-            }
-            Some(GlobalAlloc::Function { .. }) => {
-                bug!("We already checked function pointers above")
-            }
-            Some(GlobalAlloc::VTable(..)) => {
-                // No data to be accessed here. But vtables are pointer-aligned.
-                return (Size::ZERO, self.tcx.data_layout.pointer_align.abi, AllocKind::VTable);
-            }
-            // The rest must be dead.
-            None => {
-                // Deallocated pointers are allowed, we should be able to find
-                // them in the map.
-                let (size, align) = *self
-                    .memory
-                    .dead_alloc_map
-                    .get(&id)
-                    .expect("deallocated pointers should all be recorded in `dead_alloc_map`");
-                (size, align, AllocKind::Dead)
-            }
+        // # Global allocations
+        if let Some(global_alloc) = self.tcx.try_get_global_alloc(id) {
+            let (size, align) = global_alloc.size_and_align(*self.tcx, self.param_env);
+            let mutbl = global_alloc.mutability(*self.tcx, self.param_env);
+            let kind = match global_alloc {
+                GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData,
+                GlobalAlloc::Function { .. } => bug!("We already checked function pointers above"),
+                GlobalAlloc::VTable { .. } => AllocKind::VTable,
+            };
+            return AllocInfo::new(size, align, kind, mutbl);
         }
+
+        // # Dead pointers
+        let (size, align) = *self
+            .memory
+            .dead_alloc_map
+            .get(&id)
+            .expect("deallocated pointers should all be recorded in `dead_alloc_map`");
+        AllocInfo::new(size, align, AllocKind::Dead, Mutability::Not)
     }
 
     /// Obtain the size and alignment of a *live* allocation.
@@ -902,11 +884,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         id: AllocId,
         msg: CheckInAllocMsg,
     ) -> InterpResult<'tcx, (Size, Align)> {
-        let (size, align, kind) = self.get_alloc_info(id);
-        if matches!(kind, AllocKind::Dead) {
+        let info = self.get_alloc_info(id);
+        if matches!(info.kind, AllocKind::Dead) {
             throw_ub!(PointerUseAfterFree(id, msg))
         }
-        interp_ok((size, align))
+        interp_ok((info.size, info.align))
     }
 
     fn get_fn_alloc(&self, id: AllocId) -> Option<FnVal<'tcx, M::ExtraFnVal>> {
@@ -1458,7 +1440,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let ptr = scalar.to_pointer(self)?;
                 match self.ptr_try_get_alloc_id(ptr, 0) {
                     Ok((alloc_id, offset, _)) => {
-                        let (size, _align, _kind) = self.get_alloc_info(alloc_id);
+                        let size = self.get_alloc_info(alloc_id).size;
                         // If the pointer is out-of-bounds, it may be null.
                         // Note that one-past-the-end (offset == size) is still inbounds, and never null.
                         offset > size
diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs
index 5e84626f77e..f5792aba207 100644
--- a/compiler/rustc_const_eval/src/interpret/mod.rs
+++ b/compiler/rustc_const_eval/src/interpret/mod.rs
@@ -31,7 +31,7 @@ pub use self::intern::{
 };
 pub(crate) use self::intrinsics::eval_nullary_intrinsic;
 pub use self::machine::{AllocMap, Machine, MayLeak, ReturnAction, compile_time_machine};
-pub use self::memory::{AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind};
+pub use self::memory::{AllocInfo, AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind};
 use self::operand::Operand;
 pub use self::operand::{ImmTy, Immediate, OpTy};
 pub use self::place::{MPlaceTy, MemPlaceMeta, PlaceTy, Writeable};
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index cd2c1ef3613..3a68db9f7f7 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -31,8 +31,8 @@ use tracing::trace;
 
 use super::machine::AllocMap;
 use super::{
-    AllocId, AllocKind, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult,
-    MPlaceTy, Machine, MemPlaceMeta, PlaceTy, Pointer, Projectable, Scalar, ValueVisitor, err_ub,
+    AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy,
+    Machine, MemPlaceMeta, PlaceTy, Pointer, Projectable, Scalar, ValueVisitor, err_ub,
     format_interp_error,
 };
 
@@ -557,9 +557,20 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
                 if let Ok((alloc_id, _offset, _prov)) =
                     self.ecx.ptr_try_get_alloc_id(place.ptr(), 0)
                 {
-                    if let Some(GlobalAlloc::Static(did)) =
-                        self.ecx.tcx.try_get_global_alloc(alloc_id)
-                    {
+                    // Everything should be already interned.
+                    let Some(global_alloc) = self.ecx.tcx.try_get_global_alloc(alloc_id) else {
+                        assert!(self.ecx.memory.alloc_map.get(alloc_id).is_none());
+                        // We can't have *any* references to non-existing allocations in const-eval
+                        // as the rest of rustc isn't happy with them... so we throw an error, even
+                        // though for zero-sized references this isn't really UB.
+                        // A potential future alternative would be to resurrect this as a zero-sized allocation
+                        // (which codegen will then compile to an aligned dummy pointer anyway).
+                        throw_validation_failure!(self.path, DanglingPtrUseAfterFree { ptr_kind });
+                    };
+                    let (size, _align) =
+                        global_alloc.size_and_align(*self.ecx.tcx, self.ecx.param_env);
+
+                    if let GlobalAlloc::Static(did) = global_alloc {
                         let DefKind::Static { nested, .. } = self.ecx.tcx.def_kind(did) else {
                             bug!()
                         };
@@ -593,17 +604,6 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
                         }
                     }
 
-                    // Dangling and Mutability check.
-                    let (size, _align, alloc_kind) = self.ecx.get_alloc_info(alloc_id);
-                    if alloc_kind == AllocKind::Dead {
-                        // This can happen for zero-sized references. We can't have *any* references to
-                        // non-existing allocations in const-eval though, interning rejects them all as
-                        // the rest of rustc isn't happy with them... so we throw an error, even though
-                        // this isn't really UB.
-                        // A potential future alternative would be to resurrect this as a zero-sized allocation
-                        // (which codegen will then compile to an aligned dummy pointer anyway).
-                        throw_validation_failure!(self.path, DanglingPtrUseAfterFree { ptr_kind });
-                    }
                     // If this allocation has size zero, there is no actual mutability here.
                     if size != Size::ZERO {
                         // Determine whether this pointer expects to be pointing to something mutable.
@@ -618,7 +618,8 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
                             }
                         };
                         // Determine what it actually points to.
-                        let alloc_actual_mutbl = mutability(self.ecx, alloc_id);
+                        let alloc_actual_mutbl =
+                            global_alloc.mutability(*self.ecx.tcx, self.ecx.param_env);
                         // Mutable pointer to immutable memory is no good.
                         if ptr_expected_mutbl == Mutability::Mut
                             && alloc_actual_mutbl == Mutability::Not
@@ -842,9 +843,16 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
     }
 
     fn in_mutable_memory(&self, val: &PlaceTy<'tcx, M::Provenance>) -> bool {
+        debug_assert!(self.ctfe_mode.is_some());
         if let Some(mplace) = val.as_mplace_or_local().left() {
             if let Some(alloc_id) = mplace.ptr().provenance.and_then(|p| p.get_alloc_id()) {
-                mutability(self.ecx, alloc_id).is_mut()
+                let tcx = *self.ecx.tcx;
+                // Everything must be already interned.
+                let mutbl = tcx.global_alloc(alloc_id).mutability(tcx, self.ecx.param_env);
+                if let Some((_, alloc)) = self.ecx.memory.alloc_map.get(alloc_id) {
+                    assert_eq!(alloc.mutability, mutbl);
+                }
+                mutbl.is_mut()
             } else {
                 // No memory at all.
                 false
@@ -1016,53 +1024,6 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
     }
 }
 
-/// Returns whether the allocation is mutable, and whether it's actually a static.
-/// For "root" statics we look at the type to account for interior
-/// mutability; for nested statics we have no type and directly use the annotated mutability.
-fn mutability<'tcx>(ecx: &InterpCx<'tcx, impl Machine<'tcx>>, alloc_id: AllocId) -> Mutability {
-    // Let's see what kind of memory this points to.
-    // We're not using `try_global_alloc` since dangling pointers have already been handled.
-    match ecx.tcx.global_alloc(alloc_id) {
-        GlobalAlloc::Static(did) => {
-            let DefKind::Static { safety: _, mutability, nested } = ecx.tcx.def_kind(did) else {
-                bug!()
-            };
-            if nested {
-                assert!(
-                    ecx.memory.alloc_map.get(alloc_id).is_none(),
-                    "allocations of nested statics are already interned: {alloc_id:?}, {did:?}"
-                );
-                // Nested statics in a `static` are never interior mutable,
-                // so just use the declared mutability.
-                mutability
-            } else {
-                let mutability = match mutability {
-                    Mutability::Not
-                        if !ecx
-                            .tcx
-                            .type_of(did)
-                            .no_bound_vars()
-                            .expect("statics should not have generic parameters")
-                            .is_freeze(*ecx.tcx, ty::ParamEnv::reveal_all()) =>
-                    {
-                        Mutability::Mut
-                    }
-                    _ => mutability,
-                };
-                if let Some((_, alloc)) = ecx.memory.alloc_map.get(alloc_id) {
-                    assert_eq!(alloc.mutability, mutability);
-                }
-                mutability
-            }
-        }
-        GlobalAlloc::Memory(alloc) => alloc.inner().mutability,
-        GlobalAlloc::Function { .. } | GlobalAlloc::VTable(..) => {
-            // These are immutable, we better don't allow mutable pointers here.
-            Mutability::Not
-        }
-    }
-}
-
 impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, 'tcx, M> {
     type V = PlaceTy<'tcx, M::Provenance>;
 
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index b0c0e1be500..f225ad94aa7 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -12,11 +12,12 @@ use std::io::{Read, Write};
 use std::num::NonZero;
 use std::{fmt, io};
 
-use rustc_abi::{AddressSpace, Endian, HasDataLayout};
-use rustc_ast::LitKind;
+use rustc_abi::{AddressSpace, Align, Endian, HasDataLayout, Size};
+use rustc_ast::{LitKind, Mutability};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lock;
 use rustc_errors::ErrorGuaranteed;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -45,7 +46,7 @@ pub use self::pointer::{CtfeProvenance, Pointer, PointerArithmetic, Provenance};
 pub use self::value::Scalar;
 use crate::mir;
 use crate::ty::codec::{TyDecoder, TyEncoder};
-use crate::ty::{self, Instance, Ty, TyCtxt};
+use crate::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
 
 /// Uniquely identifies one of the following:
 /// - A constant
@@ -310,6 +311,85 @@ impl<'tcx> GlobalAlloc<'tcx> {
             }
         }
     }
+
+    pub fn mutability(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Mutability {
+        // Let's see what kind of memory we are.
+        match self {
+            GlobalAlloc::Static(did) => {
+                let DefKind::Static { safety: _, mutability, nested } = tcx.def_kind(did) else {
+                    bug!()
+                };
+                if nested {
+                    // Nested statics in a `static` are never interior mutable,
+                    // so just use the declared mutability.
+                    if cfg!(debug_assertions) {
+                        let alloc = tcx.eval_static_initializer(did).unwrap();
+                        assert_eq!(alloc.0.mutability, mutability);
+                    }
+                    mutability
+                } else {
+                    let mutability = match mutability {
+                        Mutability::Not
+                            if !tcx
+                                .type_of(did)
+                                .no_bound_vars()
+                                .expect("statics should not have generic parameters")
+                                .is_freeze(tcx, param_env) =>
+                        {
+                            Mutability::Mut
+                        }
+                        _ => mutability,
+                    };
+                    mutability
+                }
+            }
+            GlobalAlloc::Memory(alloc) => alloc.inner().mutability,
+            GlobalAlloc::Function { .. } | GlobalAlloc::VTable(..) => {
+                // These are immutable.
+                Mutability::Not
+            }
+        }
+    }
+
+    pub fn size_and_align(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> (Size, Align) {
+        match self {
+            GlobalAlloc::Static(def_id) => {
+                let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else {
+                    bug!("GlobalAlloc::Static is not a static")
+                };
+
+                if nested {
+                    // Nested anonymous statics are untyped, so let's get their
+                    // size and alignment from the allocation itself. This always
+                    // succeeds, as the query is fed at DefId creation time, so no
+                    // evaluation actually occurs.
+                    let alloc = tcx.eval_static_initializer(def_id).unwrap();
+                    (alloc.0.size(), alloc.0.align)
+                } else {
+                    // Use size and align of the type for everything else. We need
+                    // to do that to
+                    // * avoid cycle errors in case of self-referential statics,
+                    // * be able to get information on extern statics.
+                    let ty = tcx
+                        .type_of(def_id)
+                        .no_bound_vars()
+                        .expect("statics should not have generic parameters");
+                    let layout = tcx.layout_of(param_env.and(ty)).unwrap();
+                    assert!(layout.is_sized());
+                    (layout.size, layout.align.abi)
+                }
+            }
+            GlobalAlloc::Memory(alloc) => {
+                let alloc = alloc.inner();
+                (alloc.size(), alloc.align)
+            }
+            GlobalAlloc::Function { .. } => (Size::ZERO, Align::ONE),
+            GlobalAlloc::VTable(..) => {
+                // No data to be accessed here. But vtables are pointer-aligned.
+                return (Size::ZERO, tcx.data_layout.pointer_align.abi);
+            }
+        }
+    }
 }
 
 pub const CTFE_ALLOC_SALT: usize = 0;
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index f20ae85b8e8..21c11655110 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -155,6 +155,7 @@ pub fn feature_warn_issue(
 }
 
 /// Adds the diagnostics for a feature to an existing error.
+/// Must be a language feature!
 pub fn add_feature_diagnostics<G: EmissionGuarantee>(
     err: &mut Diag<'_, G>,
     sess: &Session,
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 470e372ee48..9d9434a7776 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -300,6 +300,7 @@ impl Session {
         self.opts.test
     }
 
+    /// `feature` must be a language feature.
     #[track_caller]
     pub fn create_feature_err<'a>(&'a self, err: impl Diagnostic<'a>, feature: Symbol) -> Diag<'a> {
         let mut err = self.dcx().create_err(err);
diff --git a/src/doc/unstable-book/src/compiler-flags/wasm-c-abi.md b/src/doc/unstable-book/src/compiler-flags/wasm-c-abi.md
index bde4bf58133..4dd8d9707d4 100644
--- a/src/doc/unstable-book/src/compiler-flags/wasm-c-abi.md
+++ b/src/doc/unstable-book/src/compiler-flags/wasm-c-abi.md
@@ -3,8 +3,8 @@
 This option controls whether Rust uses the spec-compliant C ABI when compiling
 for the `wasm32-unknown-unknown` target.
 
-This makes it possible to be ABI-compatible with all other spec-compliant Wasm
-like Rusts `wasm32-wasip1`.
+This makes it possible to be ABI-compatible with all other spec-compliant Wasm targets
+like `wasm32-wasip1`.
 
 This compiler flag is perma-unstable, as it will be enabled by default in the
 future with no option to fall back to the old non-spec-compliant ABI.
diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
index 3029c3989c9..f00a0fe7287 100644
--- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
+++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
@@ -18,7 +18,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 - MSP430
 - M68k
 - CSKY
-- s390x
 - Arm64EC
 - SPARC
 
@@ -52,11 +51,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | M68k         | `reg_addr`     | `a[0-3]`                           | `a`                  |
 | CSKY         | `reg`          | `r[0-31]`                          | `r`                  |
 | CSKY         | `freg`         | `f[0-31]`                          | `f`                  |
-| s390x        | `reg`          | `r[0-10]`, `r[12-14]`              | `r`                  |
-| s390x        | `reg_addr`     | `r[1-10]`, `r[12-14]`              | `a`                  |
-| s390x        | `freg`         | `f[0-15]`                          | `f`                  |
-| s390x        | `vreg`         | `v[0-31]`                          | Only clobbers        |
-| s390x        | `areg`         | `a[2-15]`                          | Only clobbers        |
 | SPARC        | `reg`          | `r[2-29]`                          | `r`                  |
 | SPARC        | `yreg`         | `y`                                | Only clobbers        |
 | Arm64EC      | `reg`          | `x[0-12]`, `x[15-22]`, `x[25-27]`, `x30` | `r`            |
@@ -96,10 +90,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | M68k         | `reg_data`                      | None           | `i8`, `i16`, `i32`                      |
 | CSKY         | `reg`                           | None           | `i8`, `i16`, `i32`                      |
 | CSKY         | `freg`                          | None           | `f32`,                                  |
-| s390x        | `reg`, `reg_addr`               | None           | `i8`, `i16`, `i32`, `i64`               |
-| s390x        | `freg`                          | None           | `f32`, `f64`                            |
-| s390x        | `vreg`                          | N/A            | Only clobbers                           |
-| s390x        | `areg`                          | N/A            | Only clobbers                           |
 | SPARC        | `reg`                           | None           | `i8`, `i16`, `i32`, `i64` (SPARC64 only) |
 | SPARC        | `yreg`                          | N/A            | Only clobbers                           |
 | Arm64EC      | `reg`                           | None           | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
@@ -159,8 +149,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 
 | Architecture | Unsupported register                    | Reason                                                                                                                                                                              |
 | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| All          | `sp`, `r15` (s390x), `r14`/`o6` (SPARC) | The stack pointer must be restored to its original value at the end of an asm code block.                                                                                           |
-| All          | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r11` (s390x), `r30`/`i6` (SPARC), `x29` (Arm64EC) | The frame pointer cannot be used as an input or output.                             |
+| All          | `sp`, `r14`/`o6` (SPARC)                | The stack pointer must be restored to its original value at the end of an asm code block.                                                                                           |
+| All          | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC), `x29` (Arm64EC) | The frame pointer cannot be used as an input or output.                                            |
 | All          | `r19` (Hexagon), `r29` (PowerPC), `r30` (PowerPC), `x19` (Arm64EC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames.                                                             |
 | MIPS         | `$0` or `$zero`                         | This is a constant zero register which can't be modified.                                                                                                                           |
 | MIPS         | `$1` or `$at`                           | Reserved for assembler.                                                                                                                                                             |
@@ -181,8 +171,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | CSKY         | `r15`                                   | This is the link register. |
 | CSKY         | `r[26-30]`                              | Reserved by its ABI.       |
 | CSKY         | `r31`                                   | This is the TLS register.  |
-| s390x        | `c[0-15]`                               | Reserved by the kernel. |
-| s390x        | `a[0-1]`                                | Reserved for system use. |
 | SPARC        | `r0`/`g0`                               | This is always zero and cannot be used as inputs or outputs. |
 | SPARC        | `r1`/`g1`                               | Used internally by LLVM. |
 | SPARC        | `r5`/`g5`                               | Reserved for system. (SPARC32 only) |
@@ -206,9 +194,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | PowerPC      | `reg`          | None     | `0`            | None          |
 | PowerPC      | `reg_nonzero`  | None     | `3`            | None          |
 | PowerPC      | `freg`         | None     | `0`            | None          |
-| s390x        | `reg`          | None     | `%r0`          | None          |
-| s390x        | `reg_addr`     | None     | `%r1`          | None          |
-| s390x        | `freg`         | None     | `%f0`          | None          |
 | SPARC        | `reg`          | None     | `%o0`          | None          |
 | CSKY         | `reg`          | None     | `r0`           | None          |
 | CSKY         | `freg`         | None     | `f0`           | None          |
@@ -232,8 +217,6 @@ These flags registers must be restored upon exiting the asm block if the `preser
   - The status register `r2`.
 - M68k
   - The condition code register `ccr`.
-- s390x
-  - The condition code register `cc`.
 - SPARC
   - Integer condition codes (`icc` and `xcc`)
   - Floating-point condition codes (`fcc[0-3]`)
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index 7b377a1c4cd..b9d82a08620 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -134,7 +134,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // entered for addresses that are not the base address, so even zero-sized
                 // allocations will get recognized at their base address -- but all other
                 // allocations will *not* be recognized at their "end" address.
-                let size = ecx.get_alloc_info(alloc_id).0;
+                let size = ecx.get_alloc_info(alloc_id).size;
                 if offset < size.bytes() { Some(alloc_id) } else { None }
             }
         }?;
@@ -157,25 +157,25 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
     ) -> InterpResult<'tcx, u64> {
         let ecx = self.eval_context_ref();
         let mut rng = ecx.machine.rng.borrow_mut();
-        let (size, align, kind) = ecx.get_alloc_info(alloc_id);
+        let info = ecx.get_alloc_info(alloc_id);
         // This is either called immediately after allocation (and then cached), or when
         // adjusting `tcx` pointers (which never get freed). So assert that we are looking
         // at a live allocation. This also ensures that we never re-assign an address to an
         // allocation that previously had an address, but then was freed and the address
         // information was removed.
-        assert!(!matches!(kind, AllocKind::Dead));
+        assert!(!matches!(info.kind, AllocKind::Dead));
 
         // This allocation does not have a base address yet, pick or reuse one.
         if ecx.machine.native_lib.is_some() {
             // In native lib mode, we use the "real" address of the bytes for this allocation.
             // This ensures the interpreted program and native code have the same view of memory.
-            let base_ptr = match kind {
+            let base_ptr = match info.kind {
                 AllocKind::LiveData => {
                     if ecx.tcx.try_get_global_alloc(alloc_id).is_some() {
                         // For new global allocations, we always pre-allocate the memory to be able use the machine address directly.
-                        let prepared_bytes = MiriAllocBytes::zeroed(size, align)
+                        let prepared_bytes = MiriAllocBytes::zeroed(info.size, info.align)
                             .unwrap_or_else(|| {
-                                panic!("Miri ran out of memory: cannot create allocation of {size:?} bytes")
+                                panic!("Miri ran out of memory: cannot create allocation of {size:?} bytes", size = info.size)
                             });
                         let ptr = prepared_bytes.as_ptr();
                         // Store prepared allocation space to be picked up for use later.
@@ -204,7 +204,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
         }
         // We are not in native lib mode, so we control the addresses ourselves.
         if let Some((reuse_addr, clock)) =
-            global_state.reuse.take_addr(&mut *rng, size, align, memory_kind, ecx.active_thread())
+            global_state.reuse.take_addr(&mut *rng, info.size, info.align, memory_kind, ecx.active_thread())
         {
             if let Some(clock) = clock {
                 ecx.acquire_clock(&clock);
@@ -220,14 +220,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 .next_base_addr
                 .checked_add(slack)
                 .ok_or_else(|| err_exhaust!(AddressSpaceFull))?;
-            let base_addr = align_addr(base_addr, align.bytes());
+            let base_addr = align_addr(base_addr, info.align.bytes());
 
             // Remember next base address.  If this allocation is zero-sized, leave a gap of at
             // least 1 to avoid two allocations having the same base address. (The logic in
             // `alloc_id_from_addr` assumes unique addresses, and different function/vtable pointers
             // need to be distinguishable!)
             global_state.next_base_addr = base_addr
-                .checked_add(max(size.bytes(), 1))
+                .checked_add(max(info.size.bytes(), 1))
                 .ok_or_else(|| err_exhaust!(AddressSpaceFull))?;
             // Even if `Size` didn't overflow, we might still have filled up the address space.
             if global_state.next_base_addr > ecx.target_usize_max() {
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index 72319decb94..4883613dea5 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -363,7 +363,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // If it does exist, then we have the guarantee that the
             // pointer is readable, and the implicit read access inserted
             // will never cause UB on the pointer itself.
-            let (_, _, kind) = this.get_alloc_info(*alloc_id);
+            let kind = this.get_alloc_info(*alloc_id).kind;
             if matches!(kind, AllocKind::LiveData) {
                 let alloc_extra = this.get_alloc_extra(*alloc_id)?; // can still fail for `extern static`
                 let alloc_borrow_tracker = &alloc_extra.borrow_tracker.as_ref().unwrap();
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index 47fe41d9ecd..16fcc26be33 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -626,7 +626,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
                 return interp_ok(())
             };
 
-            let (_size, _align, alloc_kind) = this.get_alloc_info(alloc_id);
+            let alloc_kind = this.get_alloc_info(alloc_id).kind;
             match alloc_kind {
                 AllocKind::LiveData => {
                     // This should have alloc_extra data, but `get_alloc_extra` can still fail
@@ -1017,7 +1017,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         // Function pointers and dead objects don't have an alloc_extra so we ignore them.
         // This is okay because accessing them is UB anyway, no need for any Stacked Borrows checks.
         // NOT using `get_alloc_extra_mut` since this might be a read-only allocation!
-        let (_size, _align, kind) = this.get_alloc_info(alloc_id);
+        let kind = this.get_alloc_info(alloc_id).kind;
         match kind {
             AllocKind::LiveData => {
                 // This should have alloc_extra data, but `get_alloc_extra` can still fail
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index 40467aa4bc1..f92150758dc 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -274,7 +274,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 .insert(new_tag, protect);
         }
 
-        let alloc_kind = this.get_alloc_info(alloc_id).2;
+        let alloc_kind = this.get_alloc_info(alloc_id).kind;
         if !matches!(alloc_kind, AllocKind::LiveData) {
             assert_eq!(ptr_size, Size::ZERO); // we did the deref check above, size has to be 0 here
             // There's not actually any bytes here where accesses could even be tracked.
@@ -538,7 +538,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         // Function pointers and dead objects don't have an alloc_extra so we ignore them.
         // This is okay because accessing them is UB anyway, no need for any Tree Borrows checks.
         // NOT using `get_alloc_extra_mut` since this might be a read-only allocation!
-        let (_size, _align, kind) = this.get_alloc_info(alloc_id);
+        let kind = this.get_alloc_info(alloc_id).kind;
         match kind {
             AllocKind::LiveData => {
                 // This should have alloc_extra data, but `get_alloc_extra` can still fail
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 72e8952c543..9668998aaa3 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -1125,10 +1125,10 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
             let Provenance::Concrete { alloc_id, .. } = ptr.provenance else {
                 panic!("extern_statics cannot contain wildcards")
             };
-            let (shim_size, shim_align, _kind) = ecx.get_alloc_info(alloc_id);
+            let info = ecx.get_alloc_info(alloc_id);
             let def_ty = ecx.tcx.type_of(def_id).instantiate_identity();
             let extern_decl_layout = ecx.tcx.layout_of(ty::ParamEnv::empty().and(def_ty)).unwrap();
-            if extern_decl_layout.size != shim_size || extern_decl_layout.align.abi != shim_align {
+            if extern_decl_layout.size != info.size || extern_decl_layout.align.abi != info.align {
                 throw_unsup_format!(
                     "extern static `{link_name}` has been declared as `{krate}::{name}` \
                     with a size of {decl_size} bytes and alignment of {decl_align} bytes, \
@@ -1138,8 +1138,8 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
                     krate = ecx.tcx.crate_name(def_id.krate),
                     decl_size = extern_decl_layout.size.bytes(),
                     decl_align = extern_decl_layout.align.abi.bytes(),
-                    shim_size = shim_size.bytes(),
-                    shim_align = shim_align.bytes(),
+                    shim_size = info.size.bytes(),
+                    shim_align = info.align.bytes(),
                 )
             }
             interp_ok(ptr)
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 18578c7acc9..b9034336924 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -300,7 +300,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let id = this.read_scalar(id)?.to_u64()?;
                 let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?;
                 if let Some(id) = std::num::NonZero::new(id).map(AllocId)
-                    && this.get_alloc_info(id).2 == AllocKind::LiveData
+                    && this.get_alloc_info(id).kind == AllocKind::LiveData
                 {
                     this.print_borrow_state(id, show_unnamed)?;
                 } else {
@@ -409,7 +409,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     );
                 }
                 if let Ok((alloc_id, offset, ..)) = this.ptr_try_get_alloc_id(ptr, 0) {
-                    let (_size, alloc_align, _kind) = this.get_alloc_info(alloc_id);
+                    let alloc_align = this.get_alloc_info(alloc_id).align;
                     // If the newly promised alignment is bigger than the native alignment of this
                     // allocation, and bigger than the previously promised alignment, then set it.
                     if align > alloc_align
diff --git a/tests/assembly/asm/s390x-types.rs b/tests/assembly/asm/s390x-types.rs
index e68b18d7aa6..b1522198a08 100644
--- a/tests/assembly/asm/s390x-types.rs
+++ b/tests/assembly/asm/s390x-types.rs
@@ -4,7 +4,7 @@
 //@[s390x] needs-llvm-components: systemz
 //@ compile-flags: -Zmerge-functions=disabled
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
diff --git a/tests/codegen/asm/s390x-clobbers.rs b/tests/codegen/asm/s390x-clobbers.rs
index 45f72206bdf..56d82b4b044 100644
--- a/tests/codegen/asm/s390x-clobbers.rs
+++ b/tests/codegen/asm/s390x-clobbers.rs
@@ -3,7 +3,7 @@
 //@[s390x] needs-llvm-components: systemz
 
 #![crate_type = "rlib"]
-#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
+#![feature(no_core, rustc_attrs, lang_items)]
 #![no_core]
 
 #[lang = "sized"]
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.rs
deleted file mode 100644
index 096036bb133..00000000000
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.rs
+++ /dev/null
@@ -1,340 +0,0 @@
-// Check that we don't suggest enabling a feature for code that's
-// not accepted even with that feature.
-
-#![allow(irrefutable_let_patterns)]
-
-use std::ops::Range;
-
-fn main() {}
-
-fn _if() {
-    if (let 0 = 1) {}
-    //~^ ERROR expected expression, found `let` statement
-
-    if (((let 0 = 1))) {}
-    //~^ ERROR expected expression, found `let` statement
-
-    if (let 0 = 1) && true {}
-    //~^ ERROR expected expression, found `let` statement
-
-    if true && (let 0 = 1) {}
-    //~^ ERROR expected expression, found `let` statement
-
-    if (let 0 = 1) && (let 0 = 1) {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR expected expression, found `let` statement
-
-    if (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR expected expression, found `let` statement
-    //~| ERROR expected expression, found `let` statement
-}
-
-fn _while() {
-    while (let 0 = 1) {}
-    //~^ ERROR expected expression, found `let` statement
-
-    while (((let 0 = 1))) {}
-    //~^ ERROR expected expression, found `let` statement
-
-    while (let 0 = 1) && true {}
-    //~^ ERROR expected expression, found `let` statement
-
-    while true && (let 0 = 1) {}
-    //~^ ERROR expected expression, found `let` statement
-
-    while (let 0 = 1) && (let 0 = 1) {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR expected expression, found `let` statement
-
-    while (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR expected expression, found `let` statement
-    //~| ERROR expected expression, found `let` statement
-}
-
-fn _macros() {
-    macro_rules! use_expr {
-        ($e:expr) => {
-            if $e {}
-            while $e {}
-        }
-    }
-    use_expr!((let 0 = 1 && 0 == 0));
-    //~^ ERROR expected expression, found `let` statement
-    use_expr!((let 0 = 1));
-    //~^ ERROR expected expression, found `let` statement
-}
-
-fn nested_within_if_expr() {
-    if &let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-
-    if !let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-    if *let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-    if -let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-
-    fn _check_try_binds_tighter() -> Result<(), ()> {
-        if let 0 = 0? {}
-        //~^ ERROR the `?` operator can only be applied to values that implement `Try`
-        Ok(())
-    }
-    if (let 0 = 0)? {}
-    //~^ ERROR expected expression, found `let` statement
-
-    if true || let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-    if (true || let 0 = 0) {}
-    //~^ ERROR expected expression, found `let` statement
-    if true && (true || let 0 = 0) {}
-    //~^ ERROR expected expression, found `let` statement
-    if true || (true && let 0 = 0) {}
-    //~^ ERROR expected expression, found `let` statement
-
-    let mut x = true;
-    if x = let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-
-    if true..(let 0 = 0) {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
-    if ..(let 0 = 0) {}
-    //~^ ERROR expected expression, found `let` statement
-    if (let 0 = 0).. {}
-    //~^ ERROR expected expression, found `let` statement
-
-    // Binds as `(let ... = true)..true &&/|| false`.
-    if let Range { start: _, end: _ } = true..true && false {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
-    if let Range { start: _, end: _ } = true..true || false {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
-
-    // Binds as `(let Range { start: F, end } = F)..(|| true)`.
-    const F: fn() -> bool = || true;
-    if let Range { start: F, end } = F..|| true {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
-
-    // Binds as `(let Range { start: true, end } = t)..(&&false)`.
-    let t = &&true;
-    if let Range { start: true, end } = t..&&false {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
-
-    if let true = let true = true {}
-    //~^ ERROR expected expression, found `let` statement
-}
-
-fn nested_within_while_expr() {
-    while &let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-
-    while !let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-    while *let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-    while -let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-
-    fn _check_try_binds_tighter() -> Result<(), ()> {
-        while let 0 = 0? {}
-        //~^ ERROR the `?` operator can only be applied to values that implement `Try`
-        Ok(())
-    }
-    while (let 0 = 0)? {}
-    //~^ ERROR expected expression, found `let` statement
-
-    while true || let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-    while (true || let 0 = 0) {}
-    //~^ ERROR expected expression, found `let` statement
-    while true && (true || let 0 = 0) {}
-    //~^ ERROR expected expression, found `let` statement
-    while true || (true && let 0 = 0) {}
-    //~^ ERROR expected expression, found `let` statement
-
-    let mut x = true;
-    while x = let 0 = 0 {}
-    //~^ ERROR expected expression, found `let` statement
-
-    while true..(let 0 = 0) {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
-    while ..(let 0 = 0) {}
-    //~^ ERROR expected expression, found `let` statement
-    while (let 0 = 0).. {}
-    //~^ ERROR expected expression, found `let` statement
-
-    // Binds as `(let ... = true)..true &&/|| false`.
-    while let Range { start: _, end: _ } = true..true && false {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
-    while let Range { start: _, end: _ } = true..true || false {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
-
-    // Binds as `(let Range { start: F, end } = F)..(|| true)`.
-    const F: fn() -> bool = || true;
-    while let Range { start: F, end } = F..|| true {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
-
-    // Binds as `(let Range { start: true, end } = t)..(&&false)`.
-    let t = &&true;
-    while let Range { start: true, end } = t..&&false {}
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
-
-    while let true = let true = true {}
-    //~^ ERROR expected expression, found `let` statement
-}
-
-fn not_error_because_clarified_intent() {
-    if let Range { start: _, end: _ } = (true..true || false) { }
-
-    if let Range { start: _, end: _ } = (true..true && false) { }
-
-    while let Range { start: _, end: _ } = (true..true || false) { }
-
-    while let Range { start: _, end: _ } = (true..true && false) { }
-}
-
-fn outside_if_and_while_expr() {
-    &let 0 = 0;
-    //~^ ERROR expected expression, found `let` statement
-
-    !let 0 = 0;
-    //~^ ERROR expected expression, found `let` statement
-    *let 0 = 0;
-    //~^ ERROR expected expression, found `let` statement
-    -let 0 = 0;
-    //~^ ERROR expected expression, found `let` statement
-    let _ = let _ = 3;
-    //~^ ERROR expected expression, found `let` statement
-
-    fn _check_try_binds_tighter() -> Result<(), ()> {
-        let 0 = 0?;
-        //~^ ERROR the `?` operator can only be applied to values that implement `Try`
-        Ok(())
-    }
-    (let 0 = 0)?;
-    //~^ ERROR expected expression, found `let` statement
-
-    true || let 0 = 0;
-    //~^ ERROR expected expression, found `let` statement
-    (true || let 0 = 0);
-    //~^ ERROR expected expression, found `let` statement
-    true && (true || let 0 = 0);
-    //~^ ERROR expected expression, found `let` statement
-
-    let mut x = true;
-    x = let 0 = 0;
-    //~^ ERROR expected expression, found `let` statement
-
-    true..(let 0 = 0);
-    //~^ ERROR expected expression, found `let` statement
-    ..(let 0 = 0);
-    //~^ ERROR expected expression, found `let` statement
-    (let 0 = 0)..;
-    //~^ ERROR expected expression, found `let` statement
-
-    (let Range { start: _, end: _ } = true..true || false);
-    //~^ ERROR mismatched types
-    //~| ERROR expected expression, found `let` statement
-
-    (let true = let true = true);
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR expected expression, found `let` statement
-
-    {
-        #[cfg(FALSE)]
-        let x = true && let y = 1;
-        //~^ ERROR expected expression, found `let` statement
-    }
-
-    #[cfg(FALSE)]
-    {
-        [1, 2, 3][let _ = ()]
-        //~^ ERROR expected expression, found `let` statement
-    }
-
-    // Check function tail position.
-    &let 0 = 0
-    //~^ ERROR expected expression, found `let` statement
-}
-
-// Let's make sure that `let` inside const generic arguments are considered.
-fn inside_const_generic_arguments() {
-    struct A<const B: bool>;
-    impl<const B: bool> A<{B}> { const O: u32 = 5; }
-
-    if let A::<{
-        true && let 1 = 1
-        //~^ ERROR expected expression, found `let` statement
-    }>::O = 5 {}
-
-    while let A::<{
-        true && let 1 = 1
-        //~^ ERROR expected expression, found `let` statement
-    }>::O = 5 {}
-
-    if A::<{
-        true && let 1 = 1
-        //~^ ERROR expected expression, found `let` statement
-    }>::O == 5 {}
-
-    // In the cases above we have `ExprKind::Block` to help us out.
-    // Below however, we would not have a block and so an implementation might go
-    // from visiting expressions to types without banning `let` expressions down the tree.
-    // This tests ensures that we are not caught by surprise should the parser
-    // admit non-IDENT expressions in const generic arguments.
-
-    if A::<
-        true && let 1 = 1
-        //~^ ERROR expressions must be enclosed in braces
-        //~| ERROR expected expression, found `let` statement
-    >::O == 5 {}
-}
-
-fn with_parenthesis() {
-    let opt = Some(Some(1i32));
-
-    if (let Some(a) = opt && true) {
-    //~^ ERROR expected expression, found `let` statement
-    }
-
-    if (let Some(a) = opt) && true {
-    //~^ ERROR expected expression, found `let` statement
-    }
-    if (let Some(a) = opt) && (let Some(b) = a) {
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR expected expression, found `let` statement
-    }
-
-    if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR expected expression, found `let` statement
-    }
-    if (let Some(a) = opt && (let Some(b) = a)) && true {
-    //~^ ERROR expected expression, found `let` statement
-    //~| ERROR expected expression, found `let` statement
-    }
-    if (let Some(a) = opt && (true)) && true {
-    //~^ ERROR expected expression, found `let` statement
-    }
-
-    #[cfg(FALSE)]
-    let x = (true && let y = 1);
-    //~^ ERROR expected expression, found `let` statement
-
-    #[cfg(FALSE)]
-    {
-        ([1, 2, 3][let _ = ()])
-        //~^ ERROR expected expression, found `let` statement
-    }
-}
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.feature.stderr
index 31f389512ed..db32b8c1de4 100644
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.stderr
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.feature.stderr
@@ -1,239 +1,239 @@
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:11:9
+  --> $DIR/disallowed-positions.rs:33: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-without-feature-gate.rs:11:9
+  --> $DIR/disallowed-positions.rs:33:9
    |
 LL |     if (let 0 = 1) {}
    |         ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:14:11
+  --> $DIR/disallowed-positions.rs:36: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-without-feature-gate.rs:14:11
+  --> $DIR/disallowed-positions.rs:36:11
    |
 LL |     if (((let 0 = 1))) {}
    |           ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:17:9
+  --> $DIR/disallowed-positions.rs:39: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-without-feature-gate.rs:17:9
+  --> $DIR/disallowed-positions.rs:39:9
    |
 LL |     if (let 0 = 1) && true {}
    |         ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:20:17
+  --> $DIR/disallowed-positions.rs:42: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-without-feature-gate.rs:20:17
+  --> $DIR/disallowed-positions.rs:42:17
    |
 LL |     if true && (let 0 = 1) {}
    |                 ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:23: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-without-feature-gate.rs:23:9
+  --> $DIR/disallowed-positions.rs:45:9
    |
 LL |     if (let 0 = 1) && (let 0 = 1) {}
    |         ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:23: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-without-feature-gate.rs:23:24
+  --> $DIR/disallowed-positions.rs:45:24
    |
 LL |     if (let 0 = 1) && (let 0 = 1) {}
    |                        ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:27:9
+  --> $DIR/disallowed-positions.rs:49:35
    |
-LL |     if (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |         ^^^^^^^^^
+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-without-feature-gate.rs:27:9
+  --> $DIR/disallowed-positions.rs:49:35
    |
-LL |     if (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+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-without-feature-gate.rs:27:22
+  --> $DIR/disallowed-positions.rs:49:48
    |
-LL |     if (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |                      ^^^^^^^^^
+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-without-feature-gate.rs:27:9
+  --> $DIR/disallowed-positions.rs:49:35
    |
-LL |     if (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+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-without-feature-gate.rs:27:35
+  --> $DIR/disallowed-positions.rs:49:61
    |
-LL |     if (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |                                   ^^^^^^^^^
+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-without-feature-gate.rs:27:9
+  --> $DIR/disallowed-positions.rs:49:35
    |
-LL |     if (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+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-without-feature-gate.rs:34:12
+  --> $DIR/disallowed-positions.rs:59: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-without-feature-gate.rs:34:12
+  --> $DIR/disallowed-positions.rs:59:12
    |
 LL |     while (let 0 = 1) {}
    |            ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:37:14
+  --> $DIR/disallowed-positions.rs:62: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-without-feature-gate.rs:37:14
+  --> $DIR/disallowed-positions.rs:62:14
    |
 LL |     while (((let 0 = 1))) {}
    |              ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:40:12
+  --> $DIR/disallowed-positions.rs:65: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-without-feature-gate.rs:40:12
+  --> $DIR/disallowed-positions.rs:65:12
    |
 LL |     while (let 0 = 1) && true {}
    |            ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:43:20
+  --> $DIR/disallowed-positions.rs:68: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-without-feature-gate.rs:43:20
+  --> $DIR/disallowed-positions.rs:68:20
    |
 LL |     while true && (let 0 = 1) {}
    |                    ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:46:12
+  --> $DIR/disallowed-positions.rs:71: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-without-feature-gate.rs:46:12
+  --> $DIR/disallowed-positions.rs:71:12
    |
 LL |     while (let 0 = 1) && (let 0 = 1) {}
    |            ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:46:27
+  --> $DIR/disallowed-positions.rs:71: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-without-feature-gate.rs:46:27
+  --> $DIR/disallowed-positions.rs:71:27
    |
 LL |     while (let 0 = 1) && (let 0 = 1) {}
    |                           ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:50:12
+  --> $DIR/disallowed-positions.rs:75:38
    |
-LL |     while (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |            ^^^^^^^^^
+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-without-feature-gate.rs:50:12
+  --> $DIR/disallowed-positions.rs:75:38
    |
-LL |     while (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+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-without-feature-gate.rs:50:25
+  --> $DIR/disallowed-positions.rs:75:51
    |
-LL |     while (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |                         ^^^^^^^^^
+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-without-feature-gate.rs:50:12
+  --> $DIR/disallowed-positions.rs:75:38
    |
-LL |     while (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+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-without-feature-gate.rs:50:38
+  --> $DIR/disallowed-positions.rs:75:64
    |
-LL |     while (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |                                      ^^^^^^^^^
+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-without-feature-gate.rs:50:12
+  --> $DIR/disallowed-positions.rs:75:38
    |
-LL |     while (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+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-without-feature-gate.rs:70:9
+  --> $DIR/disallowed-positions.rs:99:9
    |
 LL |     if &let 0 = 0 {}
    |         ^^^^^^^^^
@@ -241,7 +241,7 @@ LL |     if &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:73:9
+  --> $DIR/disallowed-positions.rs:102:9
    |
 LL |     if !let 0 = 0 {}
    |         ^^^^^^^^^
@@ -249,7 +249,7 @@ LL |     if !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:75:9
+  --> $DIR/disallowed-positions.rs:104:9
    |
 LL |     if *let 0 = 0 {}
    |         ^^^^^^^^^
@@ -257,7 +257,7 @@ LL |     if *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:77:9
+  --> $DIR/disallowed-positions.rs:106:9
    |
 LL |     if -let 0 = 0 {}
    |         ^^^^^^^^^
@@ -265,7 +265,7 @@ LL |     if -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:85:9
+  --> $DIR/disallowed-positions.rs:114:9
    |
 LL |     if (let 0 = 0)? {}
    |         ^^^^^^^^^
@@ -273,20 +273,20 @@ LL |     if (let 0 = 0)? {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:88:16
+  --> $DIR/disallowed-positions.rs:117: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-without-feature-gate.rs:88:13
+  --> $DIR/disallowed-positions.rs:117:13
    |
 LL |     if true || let 0 = 0 {}
    |             ^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:90:17
+  --> $DIR/disallowed-positions.rs:119:17
    |
 LL |     if (true || let 0 = 0) {}
    |                 ^^^^^^^^^
@@ -294,7 +294,7 @@ LL |     if (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:92:25
+  --> $DIR/disallowed-positions.rs:121:25
    |
 LL |     if true && (true || let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -302,7 +302,7 @@ LL |     if true && (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:94:25
+  --> $DIR/disallowed-positions.rs:123:25
    |
 LL |     if true || (true && let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -310,7 +310,7 @@ LL |     if true || (true && let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:98:12
+  --> $DIR/disallowed-positions.rs:127:12
    |
 LL |     if x = let 0 = 0 {}
    |            ^^^
@@ -318,7 +318,7 @@ LL |     if x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:101:15
+  --> $DIR/disallowed-positions.rs:130:15
    |
 LL |     if true..(let 0 = 0) {}
    |               ^^^^^^^^^
@@ -326,7 +326,7 @@ LL |     if true..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:104:11
+  --> $DIR/disallowed-positions.rs:133:11
    |
 LL |     if ..(let 0 = 0) {}
    |           ^^^^^^^^^
@@ -334,7 +334,7 @@ LL |     if ..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:106:9
+  --> $DIR/disallowed-positions.rs:135:9
    |
 LL |     if (let 0 = 0).. {}
    |         ^^^^^^^^^
@@ -342,7 +342,7 @@ LL |     if (let 0 = 0).. {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:110:8
+  --> $DIR/disallowed-positions.rs:139:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -350,7 +350,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:113:8
+  --> $DIR/disallowed-positions.rs:142:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -358,7 +358,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:119:8
+  --> $DIR/disallowed-positions.rs:148:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -366,7 +366,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:125:8
+  --> $DIR/disallowed-positions.rs:154:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -374,7 +374,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:129:19
+  --> $DIR/disallowed-positions.rs:158:19
    |
 LL |     if let true = let true = true {}
    |                   ^^^
@@ -382,7 +382,71 @@ LL |     if let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:134:12
+  --> $DIR/disallowed-positions.rs:161:15
+   |
+LL |     if return let 0 = 0 {}
+   |               ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:164:21
+   |
+LL |     loop { if break let 0 = 0 {} }
+   |                     ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:167:15
+   |
+LL |     if (match let 0 = 0 { _ => { false } }) {}
+   |               ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:170:9
+   |
+LL |     if (let 0 = 0, false).1 {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:173:9
+   |
+LL |     if (let 0 = 0,) {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:177:13
+   |
+LL |         if (let 0 = 0).await {}
+   |             ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:181:12
+   |
+LL |     if (|| let 0 = 0) {}
+   |            ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:184:9
+   |
+LL |     if (let 0 = 0)() {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:190:12
    |
 LL |     while &let 0 = 0 {}
    |            ^^^^^^^^^
@@ -390,7 +454,7 @@ LL |     while &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:137:12
+  --> $DIR/disallowed-positions.rs:193:12
    |
 LL |     while !let 0 = 0 {}
    |            ^^^^^^^^^
@@ -398,7 +462,7 @@ LL |     while !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:139:12
+  --> $DIR/disallowed-positions.rs:195:12
    |
 LL |     while *let 0 = 0 {}
    |            ^^^^^^^^^
@@ -406,7 +470,7 @@ LL |     while *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:141:12
+  --> $DIR/disallowed-positions.rs:197:12
    |
 LL |     while -let 0 = 0 {}
    |            ^^^^^^^^^
@@ -414,7 +478,7 @@ LL |     while -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:149:12
+  --> $DIR/disallowed-positions.rs:205:12
    |
 LL |     while (let 0 = 0)? {}
    |            ^^^^^^^^^
@@ -422,20 +486,20 @@ LL |     while (let 0 = 0)? {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:152:19
+  --> $DIR/disallowed-positions.rs:208: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-without-feature-gate.rs:152:16
+  --> $DIR/disallowed-positions.rs:208:16
    |
 LL |     while true || let 0 = 0 {}
    |                ^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:154:20
+  --> $DIR/disallowed-positions.rs:210:20
    |
 LL |     while (true || let 0 = 0) {}
    |                    ^^^^^^^^^
@@ -443,7 +507,7 @@ LL |     while (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:156:28
+  --> $DIR/disallowed-positions.rs:212:28
    |
 LL |     while true && (true || let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -451,7 +515,7 @@ LL |     while true && (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:158:28
+  --> $DIR/disallowed-positions.rs:214:28
    |
 LL |     while true || (true && let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -459,7 +523,7 @@ LL |     while true || (true && let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:162:15
+  --> $DIR/disallowed-positions.rs:218:15
    |
 LL |     while x = let 0 = 0 {}
    |               ^^^
@@ -467,7 +531,7 @@ LL |     while x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:165:18
+  --> $DIR/disallowed-positions.rs:221:18
    |
 LL |     while true..(let 0 = 0) {}
    |                  ^^^^^^^^^
@@ -475,7 +539,7 @@ LL |     while true..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:168:14
+  --> $DIR/disallowed-positions.rs:224:14
    |
 LL |     while ..(let 0 = 0) {}
    |              ^^^^^^^^^
@@ -483,7 +547,7 @@ LL |     while ..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:170:12
+  --> $DIR/disallowed-positions.rs:226:12
    |
 LL |     while (let 0 = 0).. {}
    |            ^^^^^^^^^
@@ -491,7 +555,7 @@ LL |     while (let 0 = 0).. {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:174:11
+  --> $DIR/disallowed-positions.rs:230:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -499,7 +563,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:177:11
+  --> $DIR/disallowed-positions.rs:233:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -507,7 +571,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:183:11
+  --> $DIR/disallowed-positions.rs:239:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -515,7 +579,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:189:11
+  --> $DIR/disallowed-positions.rs:245:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -523,7 +587,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:193:22
+  --> $DIR/disallowed-positions.rs:249:22
    |
 LL |     while let true = let true = true {}
    |                      ^^^
@@ -531,7 +595,71 @@ LL |     while let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:208:6
+  --> $DIR/disallowed-positions.rs:252:18
+   |
+LL |     while return let 0 = 0 {}
+   |                  ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:255:39
+   |
+LL |     'outer: loop { while break 'outer let 0 = 0 {} }
+   |                                       ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:258:18
+   |
+LL |     while (match let 0 = 0 { _ => { false } }) {}
+   |                  ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:261:12
+   |
+LL |     while (let 0 = 0, false).1 {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:264:12
+   |
+LL |     while (let 0 = 0,) {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:268:16
+   |
+LL |         while (let 0 = 0).await {}
+   |                ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:272:15
+   |
+LL |     while (|| let 0 = 0) {}
+   |               ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:275:12
+   |
+LL |     while (let 0 = 0)() {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:292:6
    |
 LL |     &let 0 = 0;
    |      ^^^
@@ -539,7 +667,7 @@ LL |     &let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:211:6
+  --> $DIR/disallowed-positions.rs:295:6
    |
 LL |     !let 0 = 0;
    |      ^^^
@@ -547,7 +675,7 @@ LL |     !let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:213:6
+  --> $DIR/disallowed-positions.rs:297:6
    |
 LL |     *let 0 = 0;
    |      ^^^
@@ -555,7 +683,7 @@ LL |     *let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:215:6
+  --> $DIR/disallowed-positions.rs:299:6
    |
 LL |     -let 0 = 0;
    |      ^^^
@@ -563,7 +691,7 @@ LL |     -let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:217:13
+  --> $DIR/disallowed-positions.rs:301:13
    |
 LL |     let _ = let _ = 3;
    |             ^^^
@@ -571,7 +699,7 @@ LL |     let _ = let _ = 3;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:225:6
+  --> $DIR/disallowed-positions.rs:309:6
    |
 LL |     (let 0 = 0)?;
    |      ^^^
@@ -579,7 +707,7 @@ LL |     (let 0 = 0)?;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:228:13
+  --> $DIR/disallowed-positions.rs:312:13
    |
 LL |     true || let 0 = 0;
    |             ^^^
@@ -587,7 +715,7 @@ LL |     true || let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:230:14
+  --> $DIR/disallowed-positions.rs:314:14
    |
 LL |     (true || let 0 = 0);
    |              ^^^
@@ -595,7 +723,7 @@ LL |     (true || let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:232:22
+  --> $DIR/disallowed-positions.rs:316:22
    |
 LL |     true && (true || let 0 = 0);
    |                      ^^^
@@ -603,7 +731,7 @@ LL |     true && (true || let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:236:9
+  --> $DIR/disallowed-positions.rs:320:9
    |
 LL |     x = let 0 = 0;
    |         ^^^
@@ -611,7 +739,7 @@ LL |     x = let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:239:12
+  --> $DIR/disallowed-positions.rs:323:12
    |
 LL |     true..(let 0 = 0);
    |            ^^^
@@ -619,7 +747,7 @@ LL |     true..(let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:241:8
+  --> $DIR/disallowed-positions.rs:325:8
    |
 LL |     ..(let 0 = 0);
    |        ^^^
@@ -627,7 +755,7 @@ LL |     ..(let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:243:6
+  --> $DIR/disallowed-positions.rs:327:6
    |
 LL |     (let 0 = 0)..;
    |      ^^^
@@ -635,7 +763,7 @@ LL |     (let 0 = 0)..;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:246:6
+  --> $DIR/disallowed-positions.rs:330:6
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |      ^^^
@@ -643,7 +771,7 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:250:6
+  --> $DIR/disallowed-positions.rs:334:6
    |
 LL |     (let true = let true = true);
    |      ^^^
@@ -651,7 +779,7 @@ LL |     (let true = let true = true);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:250:17
+  --> $DIR/disallowed-positions.rs:334:17
    |
 LL |     (let true = let true = true);
    |                 ^^^
@@ -659,7 +787,7 @@ LL |     (let true = let true = true);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:256:25
+  --> $DIR/disallowed-positions.rs:340:25
    |
 LL |         let x = true && let y = 1;
    |                         ^^^
@@ -667,7 +795,7 @@ LL |         let x = true && let y = 1;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:262:19
+  --> $DIR/disallowed-positions.rs:346:19
    |
 LL |         [1, 2, 3][let _ = ()]
    |                   ^^^
@@ -675,7 +803,7 @@ LL |         [1, 2, 3][let _ = ()]
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:267:6
+  --> $DIR/disallowed-positions.rs:351:6
    |
 LL |     &let 0 = 0
    |      ^^^
@@ -683,7 +811,7 @@ LL |     &let 0 = 0
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:277:17
+  --> $DIR/disallowed-positions.rs:362:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -691,7 +819,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:282:17
+  --> $DIR/disallowed-positions.rs:367:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -699,7 +827,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:287:17
+  --> $DIR/disallowed-positions.rs:372:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -707,7 +835,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:298:17
+  --> $DIR/disallowed-positions.rs:383:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -715,7 +843,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/disallowed-positions-without-feature-gate.rs:298:9
+  --> $DIR/disallowed-positions.rs:383:9
    |
 LL |         true && let 1 = 1
    |         ^^^^^^^^^^^^^^^^^
@@ -726,124 +854,124 @@ LL |         { true && let 1 = 1 }
    |         +                   +
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:307:9
+  --> $DIR/disallowed-positions.rs:393: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-without-feature-gate.rs:307:9
+  --> $DIR/disallowed-positions.rs:393:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:311:9
+  --> $DIR/disallowed-positions.rs:397: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-without-feature-gate.rs:311:9
+  --> $DIR/disallowed-positions.rs:397:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:314:9
+  --> $DIR/disallowed-positions.rs:400: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-without-feature-gate.rs:314:9
+  --> $DIR/disallowed-positions.rs:400:9
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |         ^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:314:32
+  --> $DIR/disallowed-positions.rs:400: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-without-feature-gate.rs:314:32
+  --> $DIR/disallowed-positions.rs:400:32
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |                                ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:319:9
+  --> $DIR/disallowed-positions.rs:408: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-without-feature-gate.rs:319:9
+  --> $DIR/disallowed-positions.rs:408:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:319:31
+  --> $DIR/disallowed-positions.rs:408: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-without-feature-gate.rs:319:31
+  --> $DIR/disallowed-positions.rs:408:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |                               ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:323:9
+  --> $DIR/disallowed-positions.rs:412: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-without-feature-gate.rs:323:9
+  --> $DIR/disallowed-positions.rs:412:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:323:31
+  --> $DIR/disallowed-positions.rs:412: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-without-feature-gate.rs:323:31
+  --> $DIR/disallowed-positions.rs:412:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |                               ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:327:9
+  --> $DIR/disallowed-positions.rs:416: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-without-feature-gate.rs:327:9
+  --> $DIR/disallowed-positions.rs:416:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:332:22
+  --> $DIR/disallowed-positions.rs:436:22
    |
 LL |     let x = (true && let y = 1);
    |                      ^^^
@@ -851,7 +979,7 @@ LL |     let x = (true && let y = 1);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:337:20
+  --> $DIR/disallowed-positions.rs:441:20
    |
 LL |         ([1, 2, 3][let _ = ()])
    |                    ^^^
@@ -859,7 +987,7 @@ LL |         ([1, 2, 3][let _ = ()])
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:63:16
+  --> $DIR/disallowed-positions.rs:91:16
    |
 LL |     use_expr!((let 0 = 1 && 0 == 0));
    |                ^^^
@@ -867,7 +995,7 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions-without-feature-gate.rs:65:16
+  --> $DIR/disallowed-positions.rs:93:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^
@@ -875,7 +1003,7 @@ LL |     use_expr!((let 0 = 1));
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions-without-feature-gate.rs:101:8
+  --> $DIR/disallowed-positions.rs:130:8
    |
 LL |     if true..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>`
@@ -884,7 +1012,7 @@ LL |     if true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions-without-feature-gate.rs:110:12
+  --> $DIR/disallowed-positions.rs:139:12
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -895,7 +1023,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions-without-feature-gate.rs:113:12
+  --> $DIR/disallowed-positions.rs:142:12
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -906,7 +1034,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions-without-feature-gate.rs:119:12
+  --> $DIR/disallowed-positions.rs:148:12
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -917,7 +1045,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions-without-feature-gate.rs:125:12
+  --> $DIR/disallowed-positions.rs:154:12
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -928,7 +1056,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions-without-feature-gate.rs:81:20
+  --> $DIR/disallowed-positions.rs:110:20
    |
 LL |         if let 0 = 0? {}
    |                    ^^ the `?` operator cannot be applied to type `{integer}`
@@ -936,7 +1064,7 @@ LL |         if let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions-without-feature-gate.rs:165:11
+  --> $DIR/disallowed-positions.rs:221:11
    |
 LL |     while true..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>`
@@ -945,7 +1073,7 @@ LL |     while true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions-without-feature-gate.rs:174:15
+  --> $DIR/disallowed-positions.rs:230:15
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -956,7 +1084,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions-without-feature-gate.rs:177:15
+  --> $DIR/disallowed-positions.rs:233:15
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -967,7 +1095,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions-without-feature-gate.rs:183:15
+  --> $DIR/disallowed-positions.rs:239:15
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -978,7 +1106,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions-without-feature-gate.rs:189:15
+  --> $DIR/disallowed-positions.rs:245:15
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -989,7 +1117,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions-without-feature-gate.rs:145:23
+  --> $DIR/disallowed-positions.rs:201:23
    |
 LL |         while let 0 = 0? {}
    |                       ^^ the `?` operator cannot be applied to type `{integer}`
@@ -997,7 +1125,7 @@ LL |         while let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions-without-feature-gate.rs:246:10
+  --> $DIR/disallowed-positions.rs:330:10
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1008,14 +1136,14 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions-without-feature-gate.rs:221:17
+  --> $DIR/disallowed-positions.rs:305: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 105 previous errors
+error: aborting due to 121 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.no_feature.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.no_feature.stderr
new file mode 100644
index 00000000000..ad16a0f8ed8
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.no_feature.stderr
@@ -0,0 +1,1239 @@
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:33: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:33:9
+   |
+LL |     if (let 0 = 1) {}
+   |         ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:36: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:36:11
+   |
+LL |     if (((let 0 = 1))) {}
+   |           ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:39: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:39:9
+   |
+LL |     if (let 0 = 1) && true {}
+   |         ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:42: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:42:17
+   |
+LL |     if true && (let 0 = 1) {}
+   |                 ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:45:9
+   |
+LL |     if (let 0 = 1) && (let 0 = 1) {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+  --> $DIR/disallowed-positions.rs:45:9
+   |
+LL |     if (let 0 = 1) && (let 0 = 1) {}
+   |         ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:45:24
+   |
+LL |     if (let 0 = 1) && (let 0 = 1) {}
+   |                        ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+  --> $DIR/disallowed-positions.rs:45:24
+   |
+LL |     if (let 0 = 1) && (let 0 = 1) {}
+   |                        ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:49: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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+LL |     while (let 0 = 1) {}
+   |            ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:62: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:62:14
+   |
+LL |     while (((let 0 = 1))) {}
+   |              ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:65: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:65:12
+   |
+LL |     while (let 0 = 1) && true {}
+   |            ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:68: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:68:20
+   |
+LL |     while true && (let 0 = 1) {}
+   |                    ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:71: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:71:12
+   |
+LL |     while (let 0 = 1) && (let 0 = 1) {}
+   |            ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:71: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:71:27
+   |
+LL |     while (let 0 = 1) && (let 0 = 1) {}
+   |                           ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:75: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:75: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:75: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:75: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:75: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:75: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:99:9
+   |
+LL |     if &let 0 = 0 {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:102:9
+   |
+LL |     if !let 0 = 0 {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:104:9
+   |
+LL |     if *let 0 = 0 {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:106:9
+   |
+LL |     if -let 0 = 0 {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:114:9
+   |
+LL |     if (let 0 = 0)? {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:117: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:117:13
+   |
+LL |     if true || let 0 = 0 {}
+   |             ^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:119:17
+   |
+LL |     if (true || let 0 = 0) {}
+   |                 ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:121:25
+   |
+LL |     if true && (true || let 0 = 0) {}
+   |                         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:123:25
+   |
+LL |     if true || (true && let 0 = 0) {}
+   |                         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:127:12
+   |
+LL |     if x = let 0 = 0 {}
+   |            ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:130:15
+   |
+LL |     if true..(let 0 = 0) {}
+   |               ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:133:11
+   |
+LL |     if ..(let 0 = 0) {}
+   |           ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:135:9
+   |
+LL |     if (let 0 = 0).. {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:139:8
+   |
+LL |     if let Range { start: _, end: _ } = true..true && false {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:142:8
+   |
+LL |     if let Range { start: _, end: _ } = true..true || false {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:148:8
+   |
+LL |     if let Range { start: F, end } = F..|| true {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:154:8
+   |
+LL |     if let Range { start: true, end } = t..&&false {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:158:19
+   |
+LL |     if let true = let true = true {}
+   |                   ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:161:15
+   |
+LL |     if return let 0 = 0 {}
+   |               ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:164:21
+   |
+LL |     loop { if break let 0 = 0 {} }
+   |                     ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:167:15
+   |
+LL |     if (match let 0 = 0 { _ => { false } }) {}
+   |               ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:170:9
+   |
+LL |     if (let 0 = 0, false).1 {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:173:9
+   |
+LL |     if (let 0 = 0,) {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:177:13
+   |
+LL |         if (let 0 = 0).await {}
+   |             ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:181:12
+   |
+LL |     if (|| let 0 = 0) {}
+   |            ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:184:9
+   |
+LL |     if (let 0 = 0)() {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:190:12
+   |
+LL |     while &let 0 = 0 {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:193:12
+   |
+LL |     while !let 0 = 0 {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:195:12
+   |
+LL |     while *let 0 = 0 {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:197:12
+   |
+LL |     while -let 0 = 0 {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:205:12
+   |
+LL |     while (let 0 = 0)? {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:208: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:208:16
+   |
+LL |     while true || let 0 = 0 {}
+   |                ^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:210:20
+   |
+LL |     while (true || let 0 = 0) {}
+   |                    ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:212:28
+   |
+LL |     while true && (true || let 0 = 0) {}
+   |                            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:214:28
+   |
+LL |     while true || (true && let 0 = 0) {}
+   |                            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:218:15
+   |
+LL |     while x = let 0 = 0 {}
+   |               ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:221:18
+   |
+LL |     while true..(let 0 = 0) {}
+   |                  ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:224:14
+   |
+LL |     while ..(let 0 = 0) {}
+   |              ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:226:12
+   |
+LL |     while (let 0 = 0).. {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:230:11
+   |
+LL |     while let Range { start: _, end: _ } = true..true && false {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:233:11
+   |
+LL |     while let Range { start: _, end: _ } = true..true || false {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:239:11
+   |
+LL |     while let Range { start: F, end } = F..|| true {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:245:11
+   |
+LL |     while let Range { start: true, end } = t..&&false {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:249:22
+   |
+LL |     while let true = let true = true {}
+   |                      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:252:18
+   |
+LL |     while return let 0 = 0 {}
+   |                  ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:255:39
+   |
+LL |     'outer: loop { while break 'outer let 0 = 0 {} }
+   |                                       ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:258:18
+   |
+LL |     while (match let 0 = 0 { _ => { false } }) {}
+   |                  ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:261:12
+   |
+LL |     while (let 0 = 0, false).1 {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:264:12
+   |
+LL |     while (let 0 = 0,) {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:268:16
+   |
+LL |         while (let 0 = 0).await {}
+   |                ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:272:15
+   |
+LL |     while (|| let 0 = 0) {}
+   |               ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:275:12
+   |
+LL |     while (let 0 = 0)() {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:292:6
+   |
+LL |     &let 0 = 0;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:295:6
+   |
+LL |     !let 0 = 0;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:297:6
+   |
+LL |     *let 0 = 0;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:299:6
+   |
+LL |     -let 0 = 0;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:301:13
+   |
+LL |     let _ = let _ = 3;
+   |             ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:309:6
+   |
+LL |     (let 0 = 0)?;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:312:13
+   |
+LL |     true || let 0 = 0;
+   |             ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:314:14
+   |
+LL |     (true || let 0 = 0);
+   |              ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:316:22
+   |
+LL |     true && (true || let 0 = 0);
+   |                      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:320:9
+   |
+LL |     x = let 0 = 0;
+   |         ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:323:12
+   |
+LL |     true..(let 0 = 0);
+   |            ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:325:8
+   |
+LL |     ..(let 0 = 0);
+   |        ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:327:6
+   |
+LL |     (let 0 = 0)..;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:330:6
+   |
+LL |     (let Range { start: _, end: _ } = true..true || false);
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:334:6
+   |
+LL |     (let true = let true = true);
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:334:17
+   |
+LL |     (let true = let true = true);
+   |                 ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:340:25
+   |
+LL |         let x = true && let y = 1;
+   |                         ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:346:19
+   |
+LL |         [1, 2, 3][let _ = ()]
+   |                   ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:351:6
+   |
+LL |     &let 0 = 0
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:362:17
+   |
+LL |         true && let 1 = 1
+   |                 ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:367:17
+   |
+LL |         true && let 1 = 1
+   |                 ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:372:17
+   |
+LL |         true && let 1 = 1
+   |                 ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:383:17
+   |
+LL |         true && let 1 = 1
+   |                 ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expressions must be enclosed in braces to be used as const generic arguments
+  --> $DIR/disallowed-positions.rs:383:9
+   |
+LL |         true && let 1 = 1
+   |         ^^^^^^^^^^^^^^^^^
+   |
+help: enclose the `const` expression in braces
+   |
+LL |         { true && let 1 = 1 }
+   |         +                   +
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:393: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:393:9
+   |
+LL |     if (let Some(a) = opt && true) {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:397: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:397:9
+   |
+LL |     if (let Some(a) = opt) && true {
+   |         ^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:400: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:400:9
+   |
+LL |     if (let Some(a) = opt) && (let Some(b) = a) {
+   |         ^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:400: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:400:32
+   |
+LL |     if (let Some(a) = opt) && (let Some(b) = a) {
+   |                                ^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:408: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:408:9
+   |
+LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:408: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:408:31
+   |
+LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
+   |                               ^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:412: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:412:9
+   |
+LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:412: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:412:31
+   |
+LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
+   |                               ^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:416: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:416:9
+   |
+LL |     if (let Some(a) = opt && (true)) && true {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:436:22
+   |
+LL |     let x = (true && let y = 1);
+   |                      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:441:20
+   |
+LL |         ([1, 2, 3][let _ = ()])
+   |                    ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:91:16
+   |
+LL |     use_expr!((let 0 = 1 && 0 == 0));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:93:16
+   |
+LL |     use_expr!((let 0 = 1));
+   |                ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:49:8
+   |
+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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:49:21
+   |
+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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:75:11
+   |
+LL |     while 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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:75:24
+   |
+LL |     while 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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:404:8
+   |
+LL |     if let Some(a) = opt && (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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:420:28
+   |
+LL |     if (true && (true)) && let Some(a) = opt {
+   |                            ^^^^^^^^^^^^^^^^^
+   |
+   = 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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:423:18
+   |
+LL |     if (true) && let Some(a) = opt {
+   |                  ^^^^^^^^^^^^^^^^^
+   |
+   = 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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:426:16
+   |
+LL |     if true && let Some(a) = opt {
+   |                ^^^^^^^^^^^^^^^^^
+   |
+   = 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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:431:8
+   |
+LL |     if let true = (true && fun()) && (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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0308]: mismatched types
+  --> $DIR/disallowed-positions.rs:130:8
+   |
+LL |     if true..(let 0 = 0) {}
+   |        ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>`
+   |
+   = note: expected type `bool`
+            found struct `std::ops::Range<bool>`
+
+error[E0308]: mismatched types
+  --> $DIR/disallowed-positions.rs:139:12
+   |
+LL |     if let Range { start: _, end: _ } = true..true && false {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
+   |            |
+   |            expected `bool`, found `Range<_>`
+   |
+   = note: expected type `bool`
+            found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+  --> $DIR/disallowed-positions.rs:142:12
+   |
+LL |     if let Range { start: _, end: _ } = true..true || false {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
+   |            |
+   |            expected `bool`, found `Range<_>`
+   |
+   = note: expected type `bool`
+            found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+  --> $DIR/disallowed-positions.rs:148:12
+   |
+LL |     if let Range { start: F, end } = F..|| true {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
+   |            |
+   |            expected fn pointer, found `Range<_>`
+   |
+   = note: expected fn pointer `fn() -> bool`
+                  found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+  --> $DIR/disallowed-positions.rs:154:12
+   |
+LL |     if let Range { start: true, end } = t..&&false {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
+   |            |
+   |            expected `bool`, found `Range<_>`
+   |
+   = note: expected type `bool`
+            found struct `std::ops::Range<_>`
+
+error[E0277]: the `?` operator can only be applied to values that implement `Try`
+  --> $DIR/disallowed-positions.rs:110:20
+   |
+LL |         if let 0 = 0? {}
+   |                    ^^ the `?` operator cannot be applied to type `{integer}`
+   |
+   = help: the trait `Try` is not implemented for `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/disallowed-positions.rs:221:11
+   |
+LL |     while true..(let 0 = 0) {}
+   |           ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>`
+   |
+   = note: expected type `bool`
+            found struct `std::ops::Range<bool>`
+
+error[E0308]: mismatched types
+  --> $DIR/disallowed-positions.rs:230:15
+   |
+LL |     while let Range { start: _, end: _ } = true..true && false {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
+   |               |
+   |               expected `bool`, found `Range<_>`
+   |
+   = note: expected type `bool`
+            found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+  --> $DIR/disallowed-positions.rs:233:15
+   |
+LL |     while let Range { start: _, end: _ } = true..true || false {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
+   |               |
+   |               expected `bool`, found `Range<_>`
+   |
+   = note: expected type `bool`
+            found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+  --> $DIR/disallowed-positions.rs:239:15
+   |
+LL |     while let Range { start: F, end } = F..|| true {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
+   |               |
+   |               expected fn pointer, found `Range<_>`
+   |
+   = note: expected fn pointer `fn() -> bool`
+                  found struct `std::ops::Range<_>`
+
+error[E0308]: mismatched types
+  --> $DIR/disallowed-positions.rs:245:15
+   |
+LL |     while let Range { start: true, end } = t..&&false {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
+   |               |
+   |               expected `bool`, found `Range<_>`
+   |
+   = note: expected type `bool`
+            found struct `std::ops::Range<_>`
+
+error[E0277]: the `?` operator can only be applied to values that implement `Try`
+  --> $DIR/disallowed-positions.rs:201:23
+   |
+LL |         while let 0 = 0? {}
+   |                       ^^ the `?` operator cannot be applied to type `{integer}`
+   |
+   = help: the trait `Try` is not implemented for `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/disallowed-positions.rs:330:10
+   |
+LL |     (let Range { start: _, end: _ } = true..true || false);
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
+   |          |
+   |          expected `bool`, found `Range<_>`
+   |
+   = note: expected type `bool`
+            found struct `std::ops::Range<_>`
+
+error[E0277]: the `?` operator can only be applied to values that implement `Try`
+  --> $DIR/disallowed-positions.rs:305: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 130 previous errors
+
+Some errors have detailed explanations: E0277, E0308, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nofeature.stderr
index ab58abf4d46..f556ecf7f91 100644
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nofeature.stderr
@@ -1,239 +1,239 @@
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:29:9
+  --> $DIR/disallowed-positions.rs:31:9
    |
 LL |     if (let 0 = 1) {}
    |         ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:29:9
+  --> $DIR/disallowed-positions.rs:31:9
    |
 LL |     if (let 0 = 1) {}
    |         ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:32:11
+  --> $DIR/disallowed-positions.rs:34: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:32:11
+  --> $DIR/disallowed-positions.rs:34: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 {}
    |         ^^^^^^^^^
    |
    = 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: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:38:17
+  --> $DIR/disallowed-positions.rs:40: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:38:17
+  --> $DIR/disallowed-positions.rs:40:17
    |
 LL |     if true && (let 0 = 1) {}
    |                 ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:41:9
+  --> $DIR/disallowed-positions.rs:43: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:41:9
+  --> $DIR/disallowed-positions.rs:43:9
    |
 LL |     if (let 0 = 1) && (let 0 = 1) {}
    |         ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:41:24
+  --> $DIR/disallowed-positions.rs:43: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:41:24
+  --> $DIR/disallowed-positions.rs:43:24
    |
 LL |     if (let 0 = 1) && (let 0 = 1) {}
    |                        ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:45:35
+  --> $DIR/disallowed-positions.rs:47: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:45:35
+  --> $DIR/disallowed-positions.rs:47: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:45:48
+  --> $DIR/disallowed-positions.rs:47: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:45:35
+  --> $DIR/disallowed-positions.rs:47: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:45:61
+  --> $DIR/disallowed-positions.rs:47: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:45:35
+  --> $DIR/disallowed-positions.rs:47: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:52:12
+  --> $DIR/disallowed-positions.rs:56: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:52:12
+  --> $DIR/disallowed-positions.rs:56:12
    |
 LL |     while (let 0 = 1) {}
    |            ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:55:14
+  --> $DIR/disallowed-positions.rs:59: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:55:14
+  --> $DIR/disallowed-positions.rs:59:14
    |
 LL |     while (((let 0 = 1))) {}
    |              ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:58:12
+  --> $DIR/disallowed-positions.rs:62: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:58:12
+  --> $DIR/disallowed-positions.rs:62:12
    |
 LL |     while (let 0 = 1) && true {}
    |            ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:61:20
+  --> $DIR/disallowed-positions.rs:65: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:61:20
+  --> $DIR/disallowed-positions.rs:65:20
    |
 LL |     while true && (let 0 = 1) {}
    |                    ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:64:12
+  --> $DIR/disallowed-positions.rs:68: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:64:12
+  --> $DIR/disallowed-positions.rs:68:12
    |
 LL |     while (let 0 = 1) && (let 0 = 1) {}
    |            ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:64:27
+  --> $DIR/disallowed-positions.rs:68: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:64:27
+  --> $DIR/disallowed-positions.rs:68:27
    |
 LL |     while (let 0 = 1) && (let 0 = 1) {}
    |                           ^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:68:38
+  --> $DIR/disallowed-positions.rs:72: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:68:38
+  --> $DIR/disallowed-positions.rs:72: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:68:51
+  --> $DIR/disallowed-positions.rs:72: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:68:38
+  --> $DIR/disallowed-positions.rs:72: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:68:64
+  --> $DIR/disallowed-positions.rs:72: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:68:38
+  --> $DIR/disallowed-positions.rs:72: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:88:9
+  --> $DIR/disallowed-positions.rs:95:9
    |
 LL |     if &let 0 = 0 {}
    |         ^^^^^^^^^
@@ -241,7 +241,7 @@ LL |     if &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:91:9
+  --> $DIR/disallowed-positions.rs:98:9
    |
 LL |     if !let 0 = 0 {}
    |         ^^^^^^^^^
@@ -249,7 +249,7 @@ LL |     if !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:93:9
+  --> $DIR/disallowed-positions.rs:100:9
    |
 LL |     if *let 0 = 0 {}
    |         ^^^^^^^^^
@@ -257,7 +257,7 @@ LL |     if *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:95:9
+  --> $DIR/disallowed-positions.rs:102:9
    |
 LL |     if -let 0 = 0 {}
    |         ^^^^^^^^^
@@ -265,7 +265,7 @@ LL |     if -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:103:9
+  --> $DIR/disallowed-positions.rs:110:9
    |
 LL |     if (let 0 = 0)? {}
    |         ^^^^^^^^^
@@ -273,20 +273,20 @@ LL |     if (let 0 = 0)? {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:106:16
+  --> $DIR/disallowed-positions.rs:113: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:106:13
+  --> $DIR/disallowed-positions.rs:113:13
    |
 LL |     if true || let 0 = 0 {}
    |             ^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:108:17
+  --> $DIR/disallowed-positions.rs:115:17
    |
 LL |     if (true || let 0 = 0) {}
    |                 ^^^^^^^^^
@@ -294,7 +294,7 @@ LL |     if (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:110:25
+  --> $DIR/disallowed-positions.rs:117:25
    |
 LL |     if true && (true || let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -302,7 +302,7 @@ LL |     if true && (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:112:25
+  --> $DIR/disallowed-positions.rs:119:25
    |
 LL |     if true || (true && let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -310,7 +310,7 @@ LL |     if true || (true && let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:116:12
+  --> $DIR/disallowed-positions.rs:123:12
    |
 LL |     if x = let 0 = 0 {}
    |            ^^^
@@ -318,7 +318,7 @@ LL |     if x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:119:15
+  --> $DIR/disallowed-positions.rs:126:15
    |
 LL |     if true..(let 0 = 0) {}
    |               ^^^^^^^^^
@@ -326,7 +326,7 @@ LL |     if true..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:122:11
+  --> $DIR/disallowed-positions.rs:129:11
    |
 LL |     if ..(let 0 = 0) {}
    |           ^^^^^^^^^
@@ -334,7 +334,7 @@ LL |     if ..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:124:9
+  --> $DIR/disallowed-positions.rs:131:9
    |
 LL |     if (let 0 = 0).. {}
    |         ^^^^^^^^^
@@ -342,7 +342,7 @@ LL |     if (let 0 = 0).. {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:128:8
+  --> $DIR/disallowed-positions.rs:135:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -350,7 +350,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:131:8
+  --> $DIR/disallowed-positions.rs:138:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -358,7 +358,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:137:8
+  --> $DIR/disallowed-positions.rs:144:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -366,7 +366,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:143:8
+  --> $DIR/disallowed-positions.rs:150:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -374,7 +374,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:147:19
+  --> $DIR/disallowed-positions.rs:154:19
    |
 LL |     if let true = let true = true {}
    |                   ^^^
@@ -382,7 +382,7 @@ LL |     if let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:152:12
+  --> $DIR/disallowed-positions.rs:160:12
    |
 LL |     while &let 0 = 0 {}
    |            ^^^^^^^^^
@@ -390,7 +390,7 @@ LL |     while &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:155:12
+  --> $DIR/disallowed-positions.rs:163:12
    |
 LL |     while !let 0 = 0 {}
    |            ^^^^^^^^^
@@ -398,7 +398,7 @@ LL |     while !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:157:12
+  --> $DIR/disallowed-positions.rs:165:12
    |
 LL |     while *let 0 = 0 {}
    |            ^^^^^^^^^
@@ -406,7 +406,7 @@ LL |     while *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:159:12
+  --> $DIR/disallowed-positions.rs:167:12
    |
 LL |     while -let 0 = 0 {}
    |            ^^^^^^^^^
@@ -414,7 +414,7 @@ LL |     while -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:167:12
+  --> $DIR/disallowed-positions.rs:175:12
    |
 LL |     while (let 0 = 0)? {}
    |            ^^^^^^^^^
@@ -422,20 +422,20 @@ LL |     while (let 0 = 0)? {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:170:19
+  --> $DIR/disallowed-positions.rs:178: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:170:16
+  --> $DIR/disallowed-positions.rs:178:16
    |
 LL |     while true || let 0 = 0 {}
    |                ^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:172:20
+  --> $DIR/disallowed-positions.rs:180:20
    |
 LL |     while (true || let 0 = 0) {}
    |                    ^^^^^^^^^
@@ -443,7 +443,7 @@ LL |     while (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:174:28
+  --> $DIR/disallowed-positions.rs:182:28
    |
 LL |     while true && (true || let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -451,7 +451,7 @@ LL |     while true && (true || let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:176:28
+  --> $DIR/disallowed-positions.rs:184:28
    |
 LL |     while true || (true && let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -459,7 +459,7 @@ LL |     while true || (true && let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:180:15
+  --> $DIR/disallowed-positions.rs:188:15
    |
 LL |     while x = let 0 = 0 {}
    |               ^^^
@@ -467,7 +467,7 @@ LL |     while x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:183:18
+  --> $DIR/disallowed-positions.rs:191:18
    |
 LL |     while true..(let 0 = 0) {}
    |                  ^^^^^^^^^
@@ -475,7 +475,7 @@ LL |     while true..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:186:14
+  --> $DIR/disallowed-positions.rs:194:14
    |
 LL |     while ..(let 0 = 0) {}
    |              ^^^^^^^^^
@@ -483,7 +483,7 @@ LL |     while ..(let 0 = 0) {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:188:12
+  --> $DIR/disallowed-positions.rs:196:12
    |
 LL |     while (let 0 = 0).. {}
    |            ^^^^^^^^^
@@ -491,7 +491,7 @@ LL |     while (let 0 = 0).. {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:192:11
+  --> $DIR/disallowed-positions.rs:200:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -499,7 +499,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:195:11
+  --> $DIR/disallowed-positions.rs:203:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -507,7 +507,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:201:11
+  --> $DIR/disallowed-positions.rs:209:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -515,7 +515,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:207:11
+  --> $DIR/disallowed-positions.rs:215:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -523,7 +523,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:211:22
+  --> $DIR/disallowed-positions.rs:219:22
    |
 LL |     while let true = let true = true {}
    |                      ^^^
@@ -531,7 +531,7 @@ LL |     while let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:226:6
+  --> $DIR/disallowed-positions.rs:236:6
    |
 LL |     &let 0 = 0;
    |      ^^^
@@ -539,7 +539,7 @@ LL |     &let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:229:6
+  --> $DIR/disallowed-positions.rs:239:6
    |
 LL |     !let 0 = 0;
    |      ^^^
@@ -547,7 +547,7 @@ LL |     !let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:231:6
+  --> $DIR/disallowed-positions.rs:241:6
    |
 LL |     *let 0 = 0;
    |      ^^^
@@ -555,7 +555,7 @@ LL |     *let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:233:6
+  --> $DIR/disallowed-positions.rs:243:6
    |
 LL |     -let 0 = 0;
    |      ^^^
@@ -563,7 +563,15 @@ LL |     -let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:241:6
+  --> $DIR/disallowed-positions.rs:245:13
+   |
+LL |     let _ = let _ = 3;
+   |             ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:253:6
    |
 LL |     (let 0 = 0)?;
    |      ^^^
@@ -571,7 +579,7 @@ LL |     (let 0 = 0)?;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:244:13
+  --> $DIR/disallowed-positions.rs:256:13
    |
 LL |     true || let 0 = 0;
    |             ^^^
@@ -579,7 +587,7 @@ LL |     true || let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:246:14
+  --> $DIR/disallowed-positions.rs:258:14
    |
 LL |     (true || let 0 = 0);
    |              ^^^
@@ -587,7 +595,7 @@ LL |     (true || let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:248:22
+  --> $DIR/disallowed-positions.rs:260:22
    |
 LL |     true && (true || let 0 = 0);
    |                      ^^^
@@ -595,7 +603,7 @@ LL |     true && (true || let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:252:9
+  --> $DIR/disallowed-positions.rs:264:9
    |
 LL |     x = let 0 = 0;
    |         ^^^
@@ -603,7 +611,7 @@ LL |     x = let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:255:12
+  --> $DIR/disallowed-positions.rs:267:12
    |
 LL |     true..(let 0 = 0);
    |            ^^^
@@ -611,7 +619,7 @@ LL |     true..(let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:257:8
+  --> $DIR/disallowed-positions.rs:269:8
    |
 LL |     ..(let 0 = 0);
    |        ^^^
@@ -619,7 +627,7 @@ LL |     ..(let 0 = 0);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:259:6
+  --> $DIR/disallowed-positions.rs:271:6
    |
 LL |     (let 0 = 0)..;
    |      ^^^
@@ -627,7 +635,7 @@ LL |     (let 0 = 0)..;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:262:6
+  --> $DIR/disallowed-positions.rs:274:6
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |      ^^^
@@ -635,7 +643,7 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:266:6
+  --> $DIR/disallowed-positions.rs:278:6
    |
 LL |     (let true = let true = true);
    |      ^^^
@@ -643,7 +651,7 @@ LL |     (let true = let true = true);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:266:17
+  --> $DIR/disallowed-positions.rs:278:17
    |
 LL |     (let true = let true = true);
    |                 ^^^
@@ -651,7 +659,7 @@ LL |     (let true = let true = true);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:272:25
+  --> $DIR/disallowed-positions.rs:284:25
    |
 LL |         let x = true && let y = 1;
    |                         ^^^
@@ -659,7 +667,7 @@ LL |         let x = true && let y = 1;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:278:19
+  --> $DIR/disallowed-positions.rs:290:19
    |
 LL |         [1, 2, 3][let _ = ()]
    |                   ^^^
@@ -667,7 +675,7 @@ LL |         [1, 2, 3][let _ = ()]
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:283:6
+  --> $DIR/disallowed-positions.rs:295:6
    |
 LL |     &let 0 = 0
    |      ^^^
@@ -675,7 +683,7 @@ LL |     &let 0 = 0
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:293:17
+  --> $DIR/disallowed-positions.rs:306:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -683,7 +691,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:298:17
+  --> $DIR/disallowed-positions.rs:311:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -691,7 +699,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:303:17
+  --> $DIR/disallowed-positions.rs:316:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -699,7 +707,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:314:17
+  --> $DIR/disallowed-positions.rs:327:17
    |
 LL |         true && let 1 = 1
    |                 ^^^
@@ -707,7 +715,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/disallowed-positions.rs:314:9
+  --> $DIR/disallowed-positions.rs:327:9
    |
 LL |         true && let 1 = 1
    |         ^^^^^^^^^^^^^^^^^
@@ -718,124 +726,124 @@ LL |         { true && let 1 = 1 }
    |         +                   +
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:323:9
+  --> $DIR/disallowed-positions.rs:337: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:323:9
+  --> $DIR/disallowed-positions.rs:337:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:327:9
+  --> $DIR/disallowed-positions.rs:341: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:327:9
+  --> $DIR/disallowed-positions.rs:341:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:330:9
+  --> $DIR/disallowed-positions.rs:344: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:330:9
+  --> $DIR/disallowed-positions.rs:344:9
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |         ^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:330:32
+  --> $DIR/disallowed-positions.rs:344: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:330:32
+  --> $DIR/disallowed-positions.rs:344:32
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |                                ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:337:9
+  --> $DIR/disallowed-positions.rs:351: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:337:9
+  --> $DIR/disallowed-positions.rs:351:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:337:31
+  --> $DIR/disallowed-positions.rs:351: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:337:31
+  --> $DIR/disallowed-positions.rs:351:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |                               ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:341:9
+  --> $DIR/disallowed-positions.rs:355: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:341:9
+  --> $DIR/disallowed-positions.rs:355:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:341:31
+  --> $DIR/disallowed-positions.rs:355: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:341:31
+  --> $DIR/disallowed-positions.rs:355:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |                               ^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:345:9
+  --> $DIR/disallowed-positions.rs:359: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:345:9
+  --> $DIR/disallowed-positions.rs:359:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:361:22
+  --> $DIR/disallowed-positions.rs:375:22
    |
 LL |     let x = (true && let y = 1);
    |                      ^^^
@@ -843,7 +851,7 @@ LL |     let x = (true && let y = 1);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:366:20
+  --> $DIR/disallowed-positions.rs:380:20
    |
 LL |         ([1, 2, 3][let _ = ()])
    |                    ^^^
@@ -851,7 +859,7 @@ LL |         ([1, 2, 3][let _ = ()])
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:81:16
+  --> $DIR/disallowed-positions.rs:87:16
    |
 LL |     use_expr!((let 0 = 1 && 0 == 0));
    |                ^^^
@@ -859,15 +867,105 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: expected expression, found `let` statement
-  --> $DIR/disallowed-positions.rs:83:16
+  --> $DIR/disallowed-positions.rs:89:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:47:8
+   |
+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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:47:21
+   |
+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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:72:11
+   |
+LL |     while 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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:72:24
+   |
+LL |     while 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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:348:8
+   |
+LL |     if let Some(a) = opt && (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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:363:28
+   |
+LL |     if (true && (true)) && let Some(a) = opt {
+   |                            ^^^^^^^^^^^^^^^^^
+   |
+   = 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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:365:18
+   |
+LL |     if (true) && let Some(a) = opt {
+   |                  ^^^^^^^^^^^^^^^^^
+   |
+   = 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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:367:16
+   |
+LL |     if true && let Some(a) = opt {
+   |                ^^^^^^^^^^^^^^^^^
+   |
+   = 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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/disallowed-positions.rs:371:8
+   |
+LL |     if let true = (true && fun()) && (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
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:119:8
+  --> $DIR/disallowed-positions.rs:126:8
    |
 LL |     if true..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>`
@@ -876,7 +974,7 @@ LL |     if true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:128:12
+  --> $DIR/disallowed-positions.rs:135:12
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -887,7 +985,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:131:12
+  --> $DIR/disallowed-positions.rs:138:12
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -898,7 +996,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:137:12
+  --> $DIR/disallowed-positions.rs:144:12
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -909,7 +1007,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:143:12
+  --> $DIR/disallowed-positions.rs:150:12
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -920,7 +1018,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:99:20
+  --> $DIR/disallowed-positions.rs:106:20
    |
 LL |         if let 0 = 0? {}
    |                    ^^ the `?` operator cannot be applied to type `{integer}`
@@ -928,7 +1026,7 @@ LL |         if let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:183:11
+  --> $DIR/disallowed-positions.rs:191:11
    |
 LL |     while true..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>`
@@ -937,7 +1035,7 @@ LL |     while true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:192:15
+  --> $DIR/disallowed-positions.rs:200:15
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -948,7 +1046,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:195:15
+  --> $DIR/disallowed-positions.rs:203:15
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -959,7 +1057,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:201:15
+  --> $DIR/disallowed-positions.rs:209:15
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -970,7 +1068,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:207:15
+  --> $DIR/disallowed-positions.rs:215:15
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -981,7 +1079,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:163:23
+  --> $DIR/disallowed-positions.rs:171:23
    |
 LL |         while let 0 = 0? {}
    |                       ^^ the `?` operator cannot be applied to type `{integer}`
@@ -989,7 +1087,7 @@ LL |         while let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:262:10
+  --> $DIR/disallowed-positions.rs:274:10
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1000,14 +1098,14 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
             found struct `std::ops::Range<_>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:237:17
+  --> $DIR/disallowed-positions.rs:249: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 104 previous errors
+error: aborting due to 114 previous errors
 
-Some errors have detailed explanations: E0277, E0308.
+Some errors have detailed explanations: E0277, E0308, E0658.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nothing.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nothing.stderr
new file mode 100644
index 00000000000..2d5fd1144ad
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nothing.stderr
@@ -0,0 +1,990 @@
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:33: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:33:9
+   |
+LL |     if (let 0 = 1) {}
+   |         ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:36: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:36:11
+   |
+LL |     if (((let 0 = 1))) {}
+   |           ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:39: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:39:9
+   |
+LL |     if (let 0 = 1) && true {}
+   |         ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:42: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:42:17
+   |
+LL |     if true && (let 0 = 1) {}
+   |                 ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:45:9
+   |
+LL |     if (let 0 = 1) && (let 0 = 1) {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+  --> $DIR/disallowed-positions.rs:45:9
+   |
+LL |     if (let 0 = 1) && (let 0 = 1) {}
+   |         ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:45:24
+   |
+LL |     if (let 0 = 1) && (let 0 = 1) {}
+   |                        ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+  --> $DIR/disallowed-positions.rs:45:24
+   |
+LL |     if (let 0 = 1) && (let 0 = 1) {}
+   |                        ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:49: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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+LL |     while (let 0 = 1) {}
+   |            ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:62: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:62:14
+   |
+LL |     while (((let 0 = 1))) {}
+   |              ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:65: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:65:12
+   |
+LL |     while (let 0 = 1) && true {}
+   |            ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:68: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:68:20
+   |
+LL |     while true && (let 0 = 1) {}
+   |                    ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:71: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:71:12
+   |
+LL |     while (let 0 = 1) && (let 0 = 1) {}
+   |            ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:71: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:71:27
+   |
+LL |     while (let 0 = 1) && (let 0 = 1) {}
+   |                           ^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:75: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:75: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:75: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:75: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:75: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:75: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:99:9
+   |
+LL |     if &let 0 = 0 {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:102:9
+   |
+LL |     if !let 0 = 0 {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:104:9
+   |
+LL |     if *let 0 = 0 {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:106:9
+   |
+LL |     if -let 0 = 0 {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:114:9
+   |
+LL |     if (let 0 = 0)? {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:117: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:117:13
+   |
+LL |     if true || let 0 = 0 {}
+   |             ^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:119:17
+   |
+LL |     if (true || let 0 = 0) {}
+   |                 ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:121:25
+   |
+LL |     if true && (true || let 0 = 0) {}
+   |                         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:123:25
+   |
+LL |     if true || (true && let 0 = 0) {}
+   |                         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:127:12
+   |
+LL |     if x = let 0 = 0 {}
+   |            ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:130:15
+   |
+LL |     if true..(let 0 = 0) {}
+   |               ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:133:11
+   |
+LL |     if ..(let 0 = 0) {}
+   |           ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:135:9
+   |
+LL |     if (let 0 = 0).. {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:139:8
+   |
+LL |     if let Range { start: _, end: _ } = true..true && false {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:142:8
+   |
+LL |     if let Range { start: _, end: _ } = true..true || false {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:148:8
+   |
+LL |     if let Range { start: F, end } = F..|| true {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:154:8
+   |
+LL |     if let Range { start: true, end } = t..&&false {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:158:19
+   |
+LL |     if let true = let true = true {}
+   |                   ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:161:15
+   |
+LL |     if return let 0 = 0 {}
+   |               ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:164:21
+   |
+LL |     loop { if break let 0 = 0 {} }
+   |                     ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:167:15
+   |
+LL |     if (match let 0 = 0 { _ => { false } }) {}
+   |               ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:170:9
+   |
+LL |     if (let 0 = 0, false).1 {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:173:9
+   |
+LL |     if (let 0 = 0,) {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:177:13
+   |
+LL |         if (let 0 = 0).await {}
+   |             ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:181:12
+   |
+LL |     if (|| let 0 = 0) {}
+   |            ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:184:9
+   |
+LL |     if (let 0 = 0)() {}
+   |         ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:190:12
+   |
+LL |     while &let 0 = 0 {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:193:12
+   |
+LL |     while !let 0 = 0 {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:195:12
+   |
+LL |     while *let 0 = 0 {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:197:12
+   |
+LL |     while -let 0 = 0 {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:205:12
+   |
+LL |     while (let 0 = 0)? {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:208: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:208:16
+   |
+LL |     while true || let 0 = 0 {}
+   |                ^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:210:20
+   |
+LL |     while (true || let 0 = 0) {}
+   |                    ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:212:28
+   |
+LL |     while true && (true || let 0 = 0) {}
+   |                            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:214:28
+   |
+LL |     while true || (true && let 0 = 0) {}
+   |                            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:218:15
+   |
+LL |     while x = let 0 = 0 {}
+   |               ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:221:18
+   |
+LL |     while true..(let 0 = 0) {}
+   |                  ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:224:14
+   |
+LL |     while ..(let 0 = 0) {}
+   |              ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:226:12
+   |
+LL |     while (let 0 = 0).. {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:230:11
+   |
+LL |     while let Range { start: _, end: _ } = true..true && false {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:233:11
+   |
+LL |     while let Range { start: _, end: _ } = true..true || false {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:239:11
+   |
+LL |     while let Range { start: F, end } = F..|| true {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:245:11
+   |
+LL |     while let Range { start: true, end } = t..&&false {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:249:22
+   |
+LL |     while let true = let true = true {}
+   |                      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:252:18
+   |
+LL |     while return let 0 = 0 {}
+   |                  ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:255:39
+   |
+LL |     'outer: loop { while break 'outer let 0 = 0 {} }
+   |                                       ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:258:18
+   |
+LL |     while (match let 0 = 0 { _ => { false } }) {}
+   |                  ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:261:12
+   |
+LL |     while (let 0 = 0, false).1 {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:264:12
+   |
+LL |     while (let 0 = 0,) {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:268:16
+   |
+LL |         while (let 0 = 0).await {}
+   |                ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:272:15
+   |
+LL |     while (|| let 0 = 0) {}
+   |               ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:275:12
+   |
+LL |     while (let 0 = 0)() {}
+   |            ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:292:6
+   |
+LL |     &let 0 = 0;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:295:6
+   |
+LL |     !let 0 = 0;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:297:6
+   |
+LL |     *let 0 = 0;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:299:6
+   |
+LL |     -let 0 = 0;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:301:13
+   |
+LL |     let _ = let _ = 3;
+   |             ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:309:6
+   |
+LL |     (let 0 = 0)?;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:312:13
+   |
+LL |     true || let 0 = 0;
+   |             ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:314:14
+   |
+LL |     (true || let 0 = 0);
+   |              ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:316:22
+   |
+LL |     true && (true || let 0 = 0);
+   |                      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:320:9
+   |
+LL |     x = let 0 = 0;
+   |         ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:323:12
+   |
+LL |     true..(let 0 = 0);
+   |            ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:325:8
+   |
+LL |     ..(let 0 = 0);
+   |        ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:327:6
+   |
+LL |     (let 0 = 0)..;
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:330:6
+   |
+LL |     (let Range { start: _, end: _ } = true..true || false);
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:334:6
+   |
+LL |     (let true = let true = true);
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:334:17
+   |
+LL |     (let true = let true = true);
+   |                 ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:340:25
+   |
+LL |         let x = true && let y = 1;
+   |                         ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:346:19
+   |
+LL |         [1, 2, 3][let _ = ()]
+   |                   ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:351:6
+   |
+LL |     &let 0 = 0
+   |      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:362:17
+   |
+LL |         true && let 1 = 1
+   |                 ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:367:17
+   |
+LL |         true && let 1 = 1
+   |                 ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:372:17
+   |
+LL |         true && let 1 = 1
+   |                 ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:383:17
+   |
+LL |         true && let 1 = 1
+   |                 ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expressions must be enclosed in braces to be used as const generic arguments
+  --> $DIR/disallowed-positions.rs:383:9
+   |
+LL |         true && let 1 = 1
+   |         ^^^^^^^^^^^^^^^^^
+   |
+help: enclose the `const` expression in braces
+   |
+LL |         { true && let 1 = 1 }
+   |         +                   +
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:393: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:393:9
+   |
+LL |     if (let Some(a) = opt && true) {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:397: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:397:9
+   |
+LL |     if (let Some(a) = opt) && true {
+   |         ^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:400: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:400:9
+   |
+LL |     if (let Some(a) = opt) && (let Some(b) = a) {
+   |         ^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:400: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:400:32
+   |
+LL |     if (let Some(a) = opt) && (let Some(b) = a) {
+   |                                ^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:408: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:408:9
+   |
+LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:408: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:408:31
+   |
+LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
+   |                               ^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:412: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:412:9
+   |
+LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:412: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:412:31
+   |
+LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
+   |                               ^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:416: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:416:9
+   |
+LL |     if (let Some(a) = opt && (true)) && true {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:436:22
+   |
+LL |     let x = (true && let y = 1);
+   |                      ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:441:20
+   |
+LL |         ([1, 2, 3][let _ = ()])
+   |                    ^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error: aborting due to 105 previous errors
+
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs
index 4ac3ea53a08..8eb8d617d58 100644
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs
@@ -1,3 +1,5 @@
+//@ revisions: no_feature feature nothing
+//@ edition: 2021
 // Here we test that `lowering` behaves correctly wrt. `let $pats = $expr` expressions.
 //
 // We want to make sure that `let` is banned in situations other than:
@@ -17,7 +19,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.
+// Avoid inflating `.stderr` with overzealous gates (or test what happens if you disable the gate)
+#![cfg_attr(not(no_feature), feature(let_chains))]
 
 #![allow(irrefutable_let_patterns)]
 
@@ -25,6 +28,7 @@ use std::ops::Range;
 
 fn main() {}
 
+#[cfg(not(nothing))]
 fn _if() {
     if (let 0 = 1) {}
     //~^ ERROR expected expression, found `let` statement
@@ -46,8 +50,11 @@ fn _if() {
     //~^ ERROR expected expression, found `let` statement
     //~| ERROR expected expression, found `let` statement
     //~| ERROR expected expression, found `let` statement
+    //[no_feature]~| ERROR `let` expressions in this position are unstable
+    //[no_feature]~| ERROR `let` expressions in this position are unstable
 }
 
+#[cfg(not(nothing))]
 fn _while() {
     while (let 0 = 1) {}
     //~^ ERROR expected expression, found `let` statement
@@ -69,8 +76,11 @@ fn _while() {
     //~^ ERROR expected expression, found `let` statement
     //~| ERROR expected expression, found `let` statement
     //~| ERROR expected expression, found `let` statement
+    //[no_feature]~| ERROR `let` expressions in this position are unstable
+    //[no_feature]~| ERROR `let` expressions in this position are unstable
 }
 
+#[cfg(not(nothing))]
 fn _macros() {
     macro_rules! use_expr {
         ($e:expr) => {
@@ -79,11 +89,12 @@ fn _macros() {
         }
     }
     use_expr!((let 0 = 1 && 0 == 0));
-    //~^ ERROR expected expression, found `let` statement
+    //[feature,no_feature]~^ ERROR expected expression, found `let` statement
     use_expr!((let 0 = 1));
-    //~^ ERROR expected expression, found `let` statement
+    //[feature,no_feature]~^ ERROR expected expression, found `let` statement
 }
 
+#[cfg(not(nothing))]
 fn nested_within_if_expr() {
     if &let 0 = 0 {}
     //~^ ERROR expected expression, found `let` statement
@@ -97,7 +108,7 @@ fn nested_within_if_expr() {
 
     fn _check_try_binds_tighter() -> Result<(), ()> {
         if let 0 = 0? {}
-        //~^ ERROR the `?` operator can only be applied to values that implement `Try`
+        //[feature,no_feature]~^ ERROR the `?` operator can only be applied to values that implement `Try`
         Ok(())
     }
     if (let 0 = 0)? {}
@@ -118,7 +129,7 @@ fn nested_within_if_expr() {
 
     if true..(let 0 = 0) {}
     //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
+    //[feature,no_feature]~| ERROR mismatched types
     if ..(let 0 = 0) {}
     //~^ ERROR expected expression, found `let` statement
     if (let 0 = 0).. {}
@@ -127,27 +138,54 @@ fn nested_within_if_expr() {
     // Binds as `(let ... = true)..true &&/|| false`.
     if let Range { start: _, end: _ } = true..true && false {}
     //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
+    //[feature,no_feature]~| ERROR mismatched types
     if let Range { start: _, end: _ } = true..true || false {}
     //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
+    //[feature,no_feature]~| ERROR mismatched types
 
     // Binds as `(let Range { start: F, end } = F)..(|| true)`.
     const F: fn() -> bool = || true;
     if let Range { start: F, end } = F..|| true {}
     //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
+    //[feature,no_feature]~| ERROR mismatched types
 
     // Binds as `(let Range { start: true, end } = t)..(&&false)`.
     let t = &&true;
     if let Range { start: true, end } = t..&&false {}
     //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
+    //[feature,no_feature]~| ERROR mismatched types
 
     if let true = let true = true {}
     //~^ ERROR expected expression, found `let` statement
+
+    if return let 0 = 0 {}
+    //~^ ERROR expected expression, found `let` statement
+
+    loop { if break let 0 = 0 {} }
+    //~^ ERROR expected expression, found `let` statement
+
+    if (match let 0 = 0 { _ => { false } }) {}
+    //~^ ERROR expected expression, found `let` statement
+
+    if (let 0 = 0, false).1 {}
+    //~^ ERROR expected expression, found `let` statement
+
+    if (let 0 = 0,) {}
+    //~^ ERROR expected expression, found `let` statement
+
+    async fn foo() {
+        if (let 0 = 0).await {}
+        //~^ ERROR expected expression, found `let` statement
+    }
+
+    if (|| let 0 = 0) {}
+    //~^ ERROR expected expression, found `let` statement
+
+    if (let 0 = 0)() {}
+    //~^ ERROR expected expression, found `let` statement
 }
 
+#[cfg(not(nothing))]
 fn nested_within_while_expr() {
     while &let 0 = 0 {}
     //~^ ERROR expected expression, found `let` statement
@@ -161,7 +199,7 @@ fn nested_within_while_expr() {
 
     fn _check_try_binds_tighter() -> Result<(), ()> {
         while let 0 = 0? {}
-        //~^ ERROR the `?` operator can only be applied to values that implement `Try`
+        //[feature,no_feature]~^ ERROR the `?` operator can only be applied to values that implement `Try`
         Ok(())
     }
     while (let 0 = 0)? {}
@@ -182,7 +220,7 @@ fn nested_within_while_expr() {
 
     while true..(let 0 = 0) {}
     //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
+    //[feature,no_feature]~| ERROR mismatched types
     while ..(let 0 = 0) {}
     //~^ ERROR expected expression, found `let` statement
     while (let 0 = 0).. {}
@@ -191,27 +229,54 @@ fn nested_within_while_expr() {
     // Binds as `(let ... = true)..true &&/|| false`.
     while let Range { start: _, end: _ } = true..true && false {}
     //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
+    //[feature,no_feature]~| ERROR mismatched types
     while let Range { start: _, end: _ } = true..true || false {}
     //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
+    //[feature,no_feature]~| ERROR mismatched types
 
     // Binds as `(let Range { start: F, end } = F)..(|| true)`.
     const F: fn() -> bool = || true;
     while let Range { start: F, end } = F..|| true {}
     //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
+    //[feature,no_feature]~| ERROR mismatched types
 
     // Binds as `(let Range { start: true, end } = t)..(&&false)`.
     let t = &&true;
     while let Range { start: true, end } = t..&&false {}
     //~^ ERROR expected expression, found `let` statement
-    //~| ERROR mismatched types
+    //[feature,no_feature]~| ERROR mismatched types
 
     while let true = let true = true {}
     //~^ ERROR expected expression, found `let` statement
+
+    while return let 0 = 0 {}
+    //~^ ERROR expected expression, found `let` statement
+
+    'outer: loop { while break 'outer let 0 = 0 {} }
+    //~^ ERROR expected expression, found `let` statement
+
+    while (match let 0 = 0 { _ => { false } }) {}
+    //~^ ERROR expected expression, found `let` statement
+
+    while (let 0 = 0, false).1 {}
+    //~^ ERROR expected expression, found `let` statement
+
+    while (let 0 = 0,) {}
+    //~^ ERROR expected expression, found `let` statement
+
+    async fn foo() {
+        while (let 0 = 0).await {}
+        //~^ ERROR expected expression, found `let` statement
+    }
+
+    while (|| let 0 = 0) {}
+    //~^ ERROR expected expression, found `let` statement
+
+    while (let 0 = 0)() {}
+    //~^ ERROR expected expression, found `let` statement
 }
 
+#[cfg(not(nothing))]
 fn not_error_because_clarified_intent() {
     if let Range { start: _, end: _ } = (true..true || false) { }
 
@@ -222,6 +287,7 @@ fn not_error_because_clarified_intent() {
     while let Range { start: _, end: _ } = (true..true && false) { }
 }
 
+#[cfg(not(nothing))]
 fn outside_if_and_while_expr() {
     &let 0 = 0;
     //~^ ERROR expected expression, found `let` statement
@@ -232,10 +298,12 @@ fn outside_if_and_while_expr() {
     //~^ ERROR expected expression, found `let` statement
     -let 0 = 0;
     //~^ ERROR expected expression, found `let` statement
+    let _ = let _ = 3;
+    //~^ ERROR expected expression, found `let` statement
 
     fn _check_try_binds_tighter() -> Result<(), ()> {
         let 0 = 0?;
-        //~^ ERROR the `?` operator can only be applied to values that implement `Try`
+        //[feature,no_feature]~^ ERROR the `?` operator can only be applied to values that implement `Try`
         Ok(())
     }
     (let 0 = 0)?;
@@ -260,8 +328,8 @@ fn outside_if_and_while_expr() {
     //~^ ERROR expected expression, found `let` statement
 
     (let Range { start: _, end: _ } = true..true || false);
-    //~^ ERROR mismatched types
-    //~| ERROR expected expression, found `let` statement
+    //~^ ERROR expected expression, found `let` statement
+    //[feature,no_feature]~| ERROR mismatched types
 
     (let true = let true = true);
     //~^ ERROR expected expression, found `let` statement
@@ -285,6 +353,7 @@ fn outside_if_and_while_expr() {
 }
 
 // Let's make sure that `let` inside const generic arguments are considered.
+#[cfg(not(nothing))]
 fn inside_const_generic_arguments() {
     struct A<const B: bool>;
     impl<const B: bool> A<{B}> { const O: u32 = 5; }
@@ -317,6 +386,7 @@ fn inside_const_generic_arguments() {
     >::O == 5 {}
 }
 
+#[cfg(not(nothing))]
 fn with_parenthesis() {
     let opt = Some(Some(1i32));
 
@@ -332,6 +402,7 @@ fn with_parenthesis() {
     //~| ERROR expected expression, found `let` statement
     }
     if let Some(a) = opt && (true && true) {
+    //[no_feature]~^ ERROR `let` expressions in this position are unstable
     }
 
     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
@@ -347,14 +418,18 @@ fn with_parenthesis() {
     }
 
     if (true && (true)) && let Some(a) = opt {
+    //[no_feature]~^ ERROR `let` expressions in this position are unstable
     }
     if (true) && let Some(a) = opt {
+    //[no_feature]~^ ERROR `let` expressions in this position are unstable
     }
     if true && let Some(a) = opt {
+    //[no_feature]~^ ERROR `let` expressions in this position are unstable
     }
 
     let fun = || true;
     if let true = (true && fun()) && (true) {
+    //[no_feature]~^ ERROR `let` expressions in this position are unstable
     }
 
     #[cfg(FALSE)]
diff --git a/tests/ui/traits/const-traits/cross-crate.rs b/tests/ui/traits/const-traits/cross-crate.rs
index 9558ec6164e..b07aa8944c0 100644
--- a/tests/ui/traits/const-traits/cross-crate.rs
+++ b/tests/ui/traits/const-traits/cross-crate.rs
@@ -18,11 +18,9 @@ const fn const_context() {
     #[cfg(any(stocknc, gatednc))]
     NonConst.func();
     //[stocknc]~^ ERROR: cannot call
-    //[stocknc]~| ERROR: cannot call
-    //[gatednc]~^^^ ERROR: the trait bound
+    //[gatednc]~^^ ERROR: the trait bound
     Const.func();
     //[stock,stocknc]~^ ERROR: cannot call
-    //[stock,stocknc]~| ERROR: cannot call
 }
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/cross-crate.stock.stderr b/tests/ui/traits/const-traits/cross-crate.stock.stderr
index b35891071b0..09bf9c023c8 100644
--- a/tests/ui/traits/const-traits/cross-crate.stock.stderr
+++ b/tests/ui/traits/const-traits/cross-crate.stock.stderr
@@ -1,28 +1,13 @@
-error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
-  --> $DIR/cross-crate.rs:23:11
+error[E0658]: cannot call conditionally-const method `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
+  --> $DIR/cross-crate.rs:22:5
    |
 LL |     Const.func();
-   |           ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   |
-LL + #![feature(const_trait_impl)]
-   |
-
-error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
-  --> $DIR/cross-crate.rs:23:11
-   |
-LL |     Const.func();
-   |           ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   |
-LL + #![feature(const_trait_impl)]
+   |     ^^^^^^^^^^^^
    |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
index 89de89159db..e52e5609b01 100644
--- a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
+++ b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
@@ -1,53 +1,23 @@
-error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
-  --> $DIR/cross-crate.rs:19:14
+error[E0658]: cannot call conditionally-const method `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
+  --> $DIR/cross-crate.rs:19:5
    |
 LL |     NonConst.func();
-   |              ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   |
-LL + #![feature(const_trait_impl)]
-   |
-
-error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
-  --> $DIR/cross-crate.rs:19:14
-   |
-LL |     NonConst.func();
-   |              ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   |
-LL + #![feature(const_trait_impl)]
+   |     ^^^^^^^^^^^^^^^
    |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
-  --> $DIR/cross-crate.rs:23:11
+error[E0658]: cannot call conditionally-const method `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
+  --> $DIR/cross-crate.rs:22:5
    |
 LL |     Const.func();
-   |           ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   |
-LL + #![feature(const_trait_impl)]
-   |
-
-error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
-  --> $DIR/cross-crate.rs:23:11
-   |
-LL |     Const.func();
-   |           ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   |
-LL + #![feature(const_trait_impl)]
+   |     ^^^^^^^^^^^^
    |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/staged-api-user-crate.rs b/tests/ui/traits/const-traits/staged-api-user-crate.rs
index c820d1ff47c..7587042cf27 100644
--- a/tests/ui/traits/const-traits/staged-api-user-crate.rs
+++ b/tests/ui/traits/const-traits/staged-api-user-crate.rs
@@ -10,8 +10,7 @@ fn non_const_context() {
 
 const fn stable_const_context() {
     Unstable::func();
-    //~^ ERROR cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions
-    //~| ERROR cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions
+    //~^ ERROR cannot call conditionally-const associated function `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions
 }
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/staged-api-user-crate.stderr b/tests/ui/traits/const-traits/staged-api-user-crate.stderr
index 24cdb1d3d5a..bf7466b8e16 100644
--- a/tests/ui/traits/const-traits/staged-api-user-crate.stderr
+++ b/tests/ui/traits/const-traits/staged-api-user-crate.stderr
@@ -1,28 +1,13 @@
-error[E0015]: cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions
+error[E0658]: cannot call conditionally-const associated function `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions
   --> $DIR/staged-api-user-crate.rs:12:5
    |
 LL |     Unstable::func();
    |     ^^^^^^^^^^^^^^^^
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   |
-LL + #![feature(const_trait_impl)]
-   |
-
-error[E0015]: cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions
-  --> $DIR/staged-api-user-crate.rs:12:5
-   |
-LL |     Unstable::func();
-   |     ^^^^^^^^^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   |
-LL + #![feature(const_trait_impl)]
-   |
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/staged-api.rs b/tests/ui/traits/const-traits/staged-api.rs
index 401a81d8142..755a4e456bc 100644
--- a/tests/ui/traits/const-traits/staged-api.rs
+++ b/tests/ui/traits/const-traits/staged-api.rs
@@ -1,10 +1,11 @@
-//@ revisions: stable unstable
+//! Checks whether we are properly enforcing recursive const stability for trait calls.
 //@ compile-flags: -Znext-solver
 
-#![cfg_attr(unstable, feature(unstable))] // The feature from the ./auxiliary/staged-api.rs file.
-#![cfg_attr(unstable, feature(local_feature))]
+#![feature(unstable)] // The feature from the ./auxiliary/staged-api.rs file.
+#![feature(local_feature)]
 #![feature(const_trait_impl)]
 #![feature(staged_api)]
+#![feature(rustc_allow_const_fn_unstable)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
 //@ aux-build: staged-api.rs
@@ -16,13 +17,16 @@ use staged_api::*;
 pub struct Foo;
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(unstable, rustc_const_unstable(feature = "local_feature", issue = "none"))]
-#[cfg_attr(stable, rustc_const_stable(feature = "local_feature", since = "1.0.0"))]
+#[rustc_const_unstable(feature = "local_feature", issue = "none")]
 impl const MyTrait for Foo {
-    //[stable]~^ ERROR trait implementations cannot be const stable yet
     fn func() {}
 }
 
+#[rustc_allow_const_fn_unstable(const_trait_impl)]
+const fn conditionally_const<T: ~const MyTrait>() {
+    T::func();
+}
+
 // Const stability has no impact on usage in non-const contexts.
 fn non_const_context() {
     Unstable::func();
@@ -32,43 +36,35 @@ fn non_const_context() {
 #[unstable(feature = "none", issue = "none")]
 const fn const_context() {
     Unstable::func();
-    //[unstable]~^ ERROR cannot use `#[feature(unstable)]`
-    //[stable]~^^ ERROR not yet stable as a const fn
+    //~^ ERROR cannot use `#[feature(const_trait_impl)]`
     Foo::func();
-    //[unstable]~^ ERROR cannot use `#[feature(local_feature)]`
-    //[stable]~^^ cannot be (indirectly) exposed to stable
-    // We get the error on `stable` since this is a trait function.
+    //~^ ERROR cannot use `#[feature(const_trait_impl)]`
     Unstable2::func();
-    //~^ ERROR not yet stable as a const fn
-    // ^ fails, because the `unstable2` feature is not active
+    //~^ ERROR cannot use `#[feature(const_trait_impl)]`
+    conditionally_const::<Foo>();
+    //~^ ERROR cannot use `#[feature(const_trait_impl)]`
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(unstable, rustc_const_unstable(feature = "local_feature", issue = "none"))]
+#[rustc_const_unstable(feature = "local_feature", issue = "none")]
 pub const fn const_context_not_const_stable() {
-    //[stable]~^ ERROR function has missing const stability attribute
     Unstable::func();
-    //[stable]~^ ERROR not yet stable as a const fn
     Foo::func();
-    //[stable]~^ cannot be (indirectly) exposed to stable
-    // We get the error on `stable` since this is a trait function.
     Unstable2::func();
-    //~^ ERROR not yet stable as a const fn
-    // ^ fails, because the `unstable2` feature is not active
+    conditionally_const::<Foo>();
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_stable(feature = "cheese", since = "1.0.0")]
 const fn stable_const_context() {
     Unstable::func();
-    //[unstable]~^ ERROR cannot use `#[feature(unstable)]`
-    //[stable]~^^ ERROR not yet stable as a const fn
+    //~^ ERROR cannot use `#[feature(const_trait_impl)]`
     Foo::func();
-    //[unstable]~^ ERROR cannot use `#[feature(local_feature)]`
-    //[stable]~^^ cannot be (indirectly) exposed to stable
-    // We get the error on `stable` since this is a trait function.
-    const_context_not_const_stable()
-    //[unstable]~^ ERROR cannot use `#[feature(local_feature)]`
+    //~^ ERROR cannot use `#[feature(const_trait_impl)]`
+    const_context_not_const_stable();
+    //~^ ERROR cannot use `#[feature(local_feature)]`
+    conditionally_const::<Foo>();
+    //~^ ERROR cannot use `#[feature(const_trait_impl)]`
 }
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/staged-api.stable.stderr b/tests/ui/traits/const-traits/staged-api.stable.stderr
deleted file mode 100644
index 8f491b2f182..00000000000
--- a/tests/ui/traits/const-traits/staged-api.stable.stderr
+++ /dev/null
@@ -1,89 +0,0 @@
-error: trait implementations cannot be const stable yet
-  --> $DIR/staged-api.rs:21:1
-   |
-LL | / impl const MyTrait for Foo {
-LL | |
-LL | |     fn func() {}
-LL | | }
-   | |_^
-   |
-   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
-
-error: function has missing const stability attribute
-  --> $DIR/staged-api.rs:48:1
-   |
-LL | / pub const fn const_context_not_const_stable() {
-LL | |
-LL | |     Unstable::func();
-LL | |
-...  |
-LL | |     // ^ fails, because the `unstable2` feature is not active
-LL | | }
-   | |_^
-
-error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:34:5
-   |
-LL |     Unstable::func();
-   |     ^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(unstable)]` to the crate attributes to enable
-
-error: `<Foo as staged_api::MyTrait>::func` cannot be (indirectly) exposed to stable
-  --> $DIR/staged-api.rs:37:5
-   |
-LL |     Foo::func();
-   |     ^^^^^^^^^^^
-   |
-   = help: either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`
-
-error: `<staged_api::Unstable2 as staged_api::MyTrait>::func` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:41:5
-   |
-LL |     Unstable2::func();
-   |     ^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(unstable2)]` to the crate attributes to enable
-
-error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:50:5
-   |
-LL |     Unstable::func();
-   |     ^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(unstable)]` to the crate attributes to enable
-
-error: `<Foo as staged_api::MyTrait>::func` cannot be (indirectly) exposed to stable
-  --> $DIR/staged-api.rs:52:5
-   |
-LL |     Foo::func();
-   |     ^^^^^^^^^^^
-   |
-   = help: either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`
-
-error: `<staged_api::Unstable2 as staged_api::MyTrait>::func` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:55:5
-   |
-LL |     Unstable2::func();
-   |     ^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(unstable2)]` to the crate attributes to enable
-
-error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:63:5
-   |
-LL |     Unstable::func();
-   |     ^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(unstable)]` to the crate attributes to enable
-
-error: `<Foo as staged_api::MyTrait>::func` cannot be (indirectly) exposed to stable
-  --> $DIR/staged-api.rs:66:5
-   |
-LL |     Foo::func();
-   |     ^^^^^^^^^^^
-   |
-   = help: either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`
-
-error: aborting due to 10 previous errors
-
diff --git a/tests/ui/traits/const-traits/staged-api.stderr b/tests/ui/traits/const-traits/staged-api.stderr
new file mode 100644
index 00000000000..29aafa4e0f3
--- /dev/null
+++ b/tests/ui/traits/const-traits/staged-api.stderr
@@ -0,0 +1,139 @@
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_trait_impl)]`
+  --> $DIR/staged-api.rs:38:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | const fn const_context() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(const_trait_impl)]
+LL | const fn const_context() {
+   |
+
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_trait_impl)]`
+  --> $DIR/staged-api.rs:40:5
+   |
+LL |     Foo::func();
+   |     ^^^^^^^^^^^
+   |
+help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | const fn const_context() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(const_trait_impl)]
+LL | const fn const_context() {
+   |
+
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_trait_impl)]`
+  --> $DIR/staged-api.rs:42:5
+   |
+LL |     Unstable2::func();
+   |     ^^^^^^^^^^^^^^^^^
+   |
+help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | const fn const_context() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(const_trait_impl)]
+LL | const fn const_context() {
+   |
+
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_trait_impl)]`
+  --> $DIR/staged-api.rs:44:5
+   |
+LL |     conditionally_const::<Foo>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | const fn const_context() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(const_trait_impl)]
+LL | const fn const_context() {
+   |
+
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_trait_impl)]`
+  --> $DIR/staged-api.rs:60:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | const fn stable_const_context() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(const_trait_impl)]
+LL | const fn stable_const_context() {
+   |
+
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_trait_impl)]`
+  --> $DIR/staged-api.rs:62:5
+   |
+LL |     Foo::func();
+   |     ^^^^^^^^^^^
+   |
+help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | const fn stable_const_context() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(const_trait_impl)]
+LL | const fn stable_const_context() {
+   |
+
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local_feature)]`
+  --> $DIR/staged-api.rs:64:5
+   |
+LL |     const_context_not_const_stable();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unsafe features
+help: if the caller is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | const fn stable_const_context() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(local_feature)]
+LL | const fn stable_const_context() {
+   |
+
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_trait_impl)]`
+  --> $DIR/staged-api.rs:66:5
+   |
+LL |     conditionally_const::<Foo>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | const fn stable_const_context() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(const_trait_impl)]
+LL | const fn stable_const_context() {
+   |
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/traits/const-traits/staged-api.unstable.stderr b/tests/ui/traits/const-traits/staged-api.unstable.stderr
deleted file mode 100644
index 76275452e90..00000000000
--- a/tests/ui/traits/const-traits/staged-api.unstable.stderr
+++ /dev/null
@@ -1,108 +0,0 @@
-error: const function that might be (indirectly) exposed to stable cannot use `#[feature(unstable)]`
-  --> $DIR/staged-api.rs:34:5
-   |
-LL |     Unstable::func();
-   |     ^^^^^^^^^^^^^^^^
-   |
-   = help: mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unsafe features
-help: if the caller is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
-   |
-LL + #[rustc_const_unstable(feature = "...", issue = "...")]
-LL | const fn const_context() {
-   |
-help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
-   |
-LL + #[rustc_allow_const_fn_unstable(unstable)]
-LL | const fn const_context() {
-   |
-
-error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local_feature)]`
-  --> $DIR/staged-api.rs:37:5
-   |
-LL |     Foo::func();
-   |     ^^^^^^^^^^^
-   |
-   = help: mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unsafe features
-help: if the caller is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
-   |
-LL + #[rustc_const_unstable(feature = "...", issue = "...")]
-LL | const fn const_context() {
-   |
-help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
-   |
-LL + #[rustc_allow_const_fn_unstable(local_feature)]
-LL | const fn const_context() {
-   |
-
-error: `<staged_api::Unstable2 as staged_api::MyTrait>::func` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:41:5
-   |
-LL |     Unstable2::func();
-   |     ^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(unstable2)]` to the crate attributes to enable
-
-error: `<staged_api::Unstable2 as staged_api::MyTrait>::func` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:55:5
-   |
-LL |     Unstable2::func();
-   |     ^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(unstable2)]` to the crate attributes to enable
-
-error: const function that might be (indirectly) exposed to stable cannot use `#[feature(unstable)]`
-  --> $DIR/staged-api.rs:63:5
-   |
-LL |     Unstable::func();
-   |     ^^^^^^^^^^^^^^^^
-   |
-   = help: mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unsafe features
-help: if the caller is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
-   |
-LL + #[rustc_const_unstable(feature = "...", issue = "...")]
-LL | const fn stable_const_context() {
-   |
-help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
-   |
-LL + #[rustc_allow_const_fn_unstable(unstable)]
-LL | const fn stable_const_context() {
-   |
-
-error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local_feature)]`
-  --> $DIR/staged-api.rs:66:5
-   |
-LL |     Foo::func();
-   |     ^^^^^^^^^^^
-   |
-   = help: mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unsafe features
-help: if the caller is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
-   |
-LL + #[rustc_const_unstable(feature = "...", issue = "...")]
-LL | const fn stable_const_context() {
-   |
-help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
-   |
-LL + #[rustc_allow_const_fn_unstable(local_feature)]
-LL | const fn stable_const_context() {
-   |
-
-error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local_feature)]`
-  --> $DIR/staged-api.rs:70:5
-   |
-LL |     const_context_not_const_stable()
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unsafe features
-help: if the caller is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
-   |
-LL + #[rustc_const_unstable(feature = "...", issue = "...")]
-LL | const fn stable_const_context() {
-   |
-help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
-   |
-LL + #[rustc_allow_const_fn_unstable(local_feature)]
-LL | const fn stable_const_context() {
-   |
-
-error: aborting due to 7 previous errors
-
diff --git a/triagebot.toml b/triagebot.toml
index 45b580787d1..95538dd7ee3 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -432,6 +432,7 @@ new_issue = true
 exclude_labels = [
     "C-tracking-issue",
     "A-diagnostics",
+    "relnotes-tracking-issue",
 ]
 
 [autolabel."WG-trait-system-refactor"]