diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 1dcde45333102..4ab0bc473057e 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -722,7 +722,8 @@ impl Features {
 
 /// Some features are not allowed to be used together at the same time, if
 /// the two are present, produce an error.
-///
-/// Currently empty, but we will probably need this again in the future,
-/// so let's keep it in for now.
-pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[];
+pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[
+    // Experimental match ergonomics rulesets are incompatible with each other, to simplify the
+    // boolean logic required to tell which typing rules to use.
+    (sym::ref_pat_eat_one_layer_2024, sym::ref_pat_eat_one_layer_2024_structural),
+];
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 36094657eafd1..cbd1db2ca2558 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -21,6 +21,7 @@ use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_session::parse::feature_err;
 use rustc_span::edit_distance::find_best_match_for_name;
+use rustc_span::edition::Edition;
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::source_map::Spanned;
 use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym};
@@ -169,15 +170,16 @@ enum AdjustMode {
     Pass,
 }
 
-/// `ref mut` patterns (explicit or match-ergonomics)
-/// are not allowed behind an `&` reference.
+/// `ref mut` bindings (explicit or match-ergonomics) are not allowed behind an `&` reference.
+/// Normally, the borrow checker enforces this, but for (currently experimental) match ergonomics,
+/// we track this when typing patterns for two purposes:
 ///
-/// This includes explicit `ref mut` behind `&` patterns
-/// that match against `&mut` references,
-/// where the code would have compiled
-/// had the pattern been written as `&mut`.
-/// However, the borrow checker will not catch
-/// this last case, so we need to throw an error ourselves.
+/// - For RFC 3627's Rule 3, when this would prevent us from binding with `ref mut`, we limit the
+///   default binding mode to be by shared `ref` when it would otherwise be `ref mut`.
+///
+/// - For RFC 3627's Rule 5, we allow `&` patterns to match against `&mut` references, treating them
+///   as if they were shared references. Since the scrutinee is mutable in this case, the borrow
+///   checker won't catch if we bind with `ref mut`, so we need to throw an error ourselves.
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 enum MutblCap {
     /// Mutability restricted to immutable.
@@ -213,7 +215,67 @@ impl MutblCap {
     }
 }
 
+/// Variations on RFC 3627's Rule 4: when do reference patterns match against inherited references?
+///
+/// "Inherited reference" designates the `&`/`&mut` types that arise from using match ergonomics, i.e.
+/// from matching a reference type with a non-reference pattern. E.g. when `Some(x)` matches on
+/// `&mut Option<&T>`, `x` gets type `&mut &T` and the outer `&mut` is considered "inherited".
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+enum InheritedRefMatchRule {
+    /// Reference patterns consume only the inherited reference if possible, regardless of whether
+    /// the underlying type being matched against is a reference type. If there is no inherited
+    /// reference, a reference will be consumed from the underlying type.
+    EatOuter,
+    /// Reference patterns consume only a reference from the underlying type if possible. If the
+    /// underlying type is not a reference type, the inherited reference will be consumed.
+    EatInner,
+    /// When the underlying type is a reference type, reference patterns consume both layers of
+    /// reference, i.e. they both reset the binding mode and consume the reference type. Reference
+    /// patterns are not permitted when there is no underlying reference type, i.e. they can't eat
+    /// only an inherited reference. This is the current stable Rust behavior.
+    EatBoth,
+}
+
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
+    /// Experimental pattern feature: after matching against a shared reference, do we limit the
+    /// default binding mode in subpatterns to be `ref` when it would otherwise be `ref mut`?
+    /// This corresponds to Rule 3 of RFC 3627.
+    fn downgrade_mut_inside_shared(&self) -> bool {
+        // NB: RFC 3627 proposes stabilizing Rule 3 in all editions. If we adopt the same behavior
+        // across all editions, this may be removed.
+        self.tcx.features().ref_pat_eat_one_layer_2024()
+            || self.tcx.features().ref_pat_eat_one_layer_2024_structural()
+    }
+
+    /// Experimental pattern feature: when do reference patterns match against inherited references?
+    /// This corresponds to variations on Rule 4 of RFC 3627.
+    fn ref_pat_matches_inherited_ref(&self, edition: Edition) -> InheritedRefMatchRule {
+        // NB: The particular rule used here is likely to differ across editions, so calls to this
+        // may need to become edition checks after match ergonomics stabilize.
+        if edition.at_least_rust_2024() {
+            if self.tcx.features().ref_pat_eat_one_layer_2024() {
+                InheritedRefMatchRule::EatOuter
+            } else if self.tcx.features().ref_pat_eat_one_layer_2024_structural() {
+                InheritedRefMatchRule::EatInner
+            } else {
+                // Currently, matching against an inherited ref on edition 2024 is an error.
+                // Use `EatBoth` as a fallback to be similar to stable Rust.
+                InheritedRefMatchRule::EatBoth
+            }
+        } else {
+            InheritedRefMatchRule::EatBoth
+        }
+    }
+
+    /// Experimental pattern feature: do `&` patterns match against `&mut` references, treating them
+    /// as if they were shared references? This corresponds to Rule 5 of RFC 3627.
+    fn ref_pat_matches_mut_ref(&self) -> bool {
+        // NB: RFC 3627 proposes stabilizing Rule 5 in all editions. If we adopt the same behavior
+        // across all editions, this may be removed.
+        self.tcx.features().ref_pat_eat_one_layer_2024()
+            || self.tcx.features().ref_pat_eat_one_layer_2024_structural()
+    }
+
     /// Type check the given top level pattern against the `expected` type.
     ///
     /// If a `Some(span)` is provided and `origin_expr` holds,
@@ -474,13 +536,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             });
         }
 
-        let features = self.tcx.features();
-        if features.ref_pat_eat_one_layer_2024() || features.ref_pat_eat_one_layer_2024_structural()
-        {
+        if self.downgrade_mut_inside_shared() {
             def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl());
-            if def_br == ByRef::Yes(Mutability::Not) {
-                max_ref_mutbl = MutblCap::Not;
-            }
+        }
+        if def_br == ByRef::Yes(Mutability::Not) {
+            max_ref_mutbl = MutblCap::Not;
         }
 
         if !pat_adjustments.is_empty() {
@@ -731,6 +791,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Determine the binding mode...
         let bm = match user_bind_annot {
             BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
+                // Only mention the experimental `mut_ref` feature if if we're in edition 2024 and
+                // using other experimental matching features compatible with it.
                 if pat.span.at_least_rust_2024()
                     && (self.tcx.features().ref_pat_eat_one_layer_2024()
                         || self.tcx.features().ref_pat_eat_one_layer_2024_structural())
@@ -2228,55 +2290,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         mut pat_info: PatInfo<'_, 'tcx>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
-        let features = tcx.features();
-        let ref_pat_eat_one_layer_2024 = features.ref_pat_eat_one_layer_2024();
-        let ref_pat_eat_one_layer_2024_structural =
-            features.ref_pat_eat_one_layer_2024_structural();
-
-        let no_ref_mut_behind_and =
-            ref_pat_eat_one_layer_2024 || ref_pat_eat_one_layer_2024_structural;
-        let new_match_ergonomics = pat.span.at_least_rust_2024() && no_ref_mut_behind_and;
 
         let pat_prefix_span =
             inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end));
 
-        if no_ref_mut_behind_and {
-            if pat_mutbl == Mutability::Not {
-                // Prevent the inner pattern from binding with `ref mut`.
-                pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span);
-            }
-        } else {
-            pat_info.max_ref_mutbl = MutblCap::Mut;
+        let ref_pat_matches_mut_ref = self.ref_pat_matches_mut_ref();
+        if ref_pat_matches_mut_ref && pat_mutbl == Mutability::Not {
+            // If `&` patterns can match against mutable reference types (RFC 3627, Rule 5), we need
+            // to prevent subpatterns from binding with `ref mut`. Subpatterns of a shared reference
+            // pattern should have read-only access to the scrutinee, and the borrow checker won't
+            // catch it in this case.
+            pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span);
         }
 
         expected = self.try_structurally_resolve_type(pat.span, expected);
-        if new_match_ergonomics {
-            if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
-                if !ref_pat_eat_one_layer_2024 && let ty::Ref(_, _, r_mutbl) = *expected.kind() {
-                    // Don't attempt to consume inherited reference
-                    pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(r_mutbl);
-                } else {
+        // Determine whether we're consuming an inherited reference and resetting the default
+        // binding mode, based on edition and enabled experimental features.
+        if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
+            match self.ref_pat_matches_inherited_ref(pat.span.edition()) {
+                InheritedRefMatchRule::EatOuter => {
                     // ref pattern attempts to consume inherited reference
                     if pat_mutbl > inh_mut {
                         // Tried to match inherited `ref` with `&mut`
-                        if !ref_pat_eat_one_layer_2024_structural {
-                            let err_msg = "mismatched types";
-                            let err = if let Some(span) = pat_prefix_span {
-                                let mut err = self.dcx().struct_span_err(span, err_msg);
-                                err.code(E0308);
-                                err.note("cannot match inherited `&` with `&mut` pattern");
-                                err.span_suggestion_verbose(
-                                    span,
-                                    "replace this `&mut` pattern with `&`",
-                                    "&",
-                                    Applicability::MachineApplicable,
-                                );
-                                err
-                            } else {
-                                self.dcx().struct_span_err(pat.span, err_msg)
-                            };
-                            err.emit();
+                        // NB: This assumes that `&` patterns can match against mutable references
+                        // (RFC 3627, Rule 5). If we implement a pattern typing ruleset with Rule 4E
+                        // but not Rule 5, we'll need to check that here.
+                        debug_assert!(ref_pat_matches_mut_ref);
+                        let err_msg = "mismatched types";
+                        let err = if let Some(span) = pat_prefix_span {
+                            let mut err = self.dcx().struct_span_err(span, err_msg);
+                            err.code(E0308);
+                            err.note("cannot match inherited `&` with `&mut` pattern");
+                            err.span_suggestion_verbose(
+                                span,
+                                "replace this `&mut` pattern with `&`",
+                                "&",
+                                Applicability::MachineApplicable,
+                            );
+                            err
+                        } else {
+                            self.dcx().struct_span_err(pat.span, err_msg)
+                        };
+                        err.emit();
+                    }
 
+                    pat_info.binding_mode = ByRef::No;
+                    self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
+                    self.check_pat(inner, expected, pat_info);
+                    return expected;
+                }
+                InheritedRefMatchRule::EatInner => {
+                    if let ty::Ref(_, _, r_mutbl) = *expected.kind() {
+                        // Match against the reference type; don't consume the inherited ref.
+                        pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(r_mutbl);
+                    } else {
+                        // The expected type isn't a reference, so match against the inherited ref.
+                        if pat_mutbl > inh_mut {
+                            // We can't match an inherited shared reference with `&mut`. This will
+                            // be a type error later, since we're matching a reference pattern
+                            // against a non-reference type.
+                            // NB: This assumes that `&` patterns can match against mutable
+                            // references (RFC 3627, Rule 5). If we implement a pattern typing
+                            // ruleset with Rule 4 but not Rule 5, we'll need to check that here.
+                            debug_assert!(ref_pat_matches_mut_ref);
+                        } else {
                             pat_info.binding_mode = ByRef::No;
                             self.typeck_results
                                 .borrow_mut()
@@ -2285,24 +2362,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             self.check_pat(inner, expected, pat_info);
                             return expected;
                         }
-                    } else {
-                        pat_info.binding_mode = ByRef::No;
-                        self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
-                        self.check_pat(inner, expected, pat_info);
-                        return expected;
                     }
                 }
-            }
-        } else {
-            // Reset binding mode on old editions
-            if pat_info.binding_mode != ByRef::No {
-                pat_info.binding_mode = ByRef::No;
-                self.add_rust_2024_migration_desugared_pat(
-                    pat_info.top_info.hir_id,
-                    pat.span,
-                    inner.span,
-                    "cannot implicitly match against multiple layers of reference",
-                )
+                InheritedRefMatchRule::EatBoth => {
+                    // Reset binding mode on old editions
+                    pat_info.binding_mode = ByRef::No;
+                    self.add_rust_2024_migration_desugared_pat(
+                        pat_info.top_info.hir_id,
+                        pat.span,
+                        inner.span,
+                        "cannot implicitly match against multiple layers of reference",
+                    )
+                }
             }
         }
 
@@ -2317,10 +2388,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 debug!("check_pat_ref: expected={:?}", expected);
                 match *expected.kind() {
                     ty::Ref(_, r_ty, r_mutbl)
-                        if (no_ref_mut_behind_and && r_mutbl >= pat_mutbl)
+                        if (ref_pat_matches_mut_ref && r_mutbl >= pat_mutbl)
                             || r_mutbl == pat_mutbl =>
                     {
-                        if no_ref_mut_behind_and && r_mutbl == Mutability::Not {
+                        if r_mutbl == Mutability::Not {
                             pat_info.max_ref_mutbl = MutblCap::Not;
                         }
 
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index a13b00e192167..6631086720068 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -1086,14 +1086,7 @@ fn find_fallback_pattern_typo<'tcx>(
                 let vis = cx.tcx.visibility(item.owner_id);
                 if vis.is_accessible_from(parent, cx.tcx) {
                     accessible.push(item_name);
-                    let path = if item_name == name {
-                        // We know that the const wasn't in scope because it has the exact
-                        // same name, so we suggest the full path.
-                        with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id))
-                    } else {
-                        // The const is likely just typoed, and nothing else.
-                        cx.tcx.def_path_str(item.owner_id)
-                    };
+                    let path = with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id));
                     accessible_path.push(path);
                 } else if name == item_name {
                     // The const exists somewhere in this crate, but it can't be imported
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 25e35fead7e83..b6b2971263a63 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -6,15 +6,14 @@ use std::mem;
 
 use rustc_ast::attr::AttributeExt;
 use rustc_ast::expand::StrippedCfgItem;
-use rustc_ast::{self as ast, Crate, Inline, ItemKind, ModKind, NodeId, attr};
+use rustc_ast::{self as ast, Crate, NodeId, attr};
 use rustc_ast_pretty::pprust;
 use rustc_attr_parsing::StabilityLevel;
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, StashKey};
 use rustc_expand::base::{
-    Annotatable, DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension,
-    SyntaxExtensionKind,
+    DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension, SyntaxExtensionKind,
 };
 use rustc_expand::compile_declarative_macro;
 use rustc_expand::expand::{
@@ -26,8 +25,8 @@ use rustc_middle::middle::stability;
 use rustc_middle::ty::{RegisteredTools, TyCtxt, Visibility};
 use rustc_session::lint::BuiltinLintDiag;
 use rustc_session::lint::builtin::{
-    LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, SOFT_UNSTABLE,
-    UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_MACRO_RULES, UNUSED_MACROS,
+    LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
+    UNUSED_MACRO_RULES, UNUSED_MACROS,
 };
 use rustc_session::parse::feature_err;
 use rustc_span::edit_distance::edit_distance;
@@ -157,26 +156,6 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools {
     registered_tools
 }
 
-// Some feature gates for inner attributes are reported as lints for backward compatibility.
-fn soft_custom_inner_attributes_gate(path: &ast::Path, invoc: &Invocation) -> bool {
-    match &path.segments[..] {
-        // `#![test]`
-        [seg] if seg.ident.name == sym::test => return true,
-        // `#![rustfmt::skip]` on out-of-line modules
-        [seg1, seg2] if seg1.ident.name == sym::rustfmt && seg2.ident.name == sym::skip => {
-            if let InvocationKind::Attr { item, .. } = &invoc.kind {
-                if let Annotatable::Item(item) = item {
-                    if let ItemKind::Mod(_, ModKind::Loaded(_, Inline::No, _, _)) = item.kind {
-                        return true;
-                    }
-                }
-            }
-        }
-        _ => {}
-    }
-    false
-}
-
 impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
     fn next_node_id(&mut self) -> NodeId {
         self.next_node_id()
@@ -317,7 +296,6 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
             parent_scope,
             node_id,
             force,
-            soft_custom_inner_attributes_gate(path, invoc),
             deleg_impl,
             looks_like_invoc_in_mod_inert_attr,
         )?;
@@ -549,7 +527,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         parent_scope: &ParentScope<'ra>,
         node_id: NodeId,
         force: bool,
-        soft_custom_inner_attributes_gate: bool,
         deleg_impl: Option<LocalDefId>,
         invoc_in_mod_inert_attr: Option<LocalDefId>,
     ) -> Result<(Lrc<SyntaxExtension>, Res), Indeterminate> {
@@ -667,22 +644,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 Res::NonMacroAttr(..) => false,
                 _ => unreachable!(),
             };
-            if soft_custom_inner_attributes_gate {
-                self.tcx.sess.psess.buffer_lint(
-                    SOFT_UNSTABLE,
-                    path.span,
-                    node_id,
-                    BuiltinLintDiag::InnerAttributeUnstable { is_macro },
-                );
+            let msg = if is_macro {
+                "inner macro attributes are unstable"
             } else {
-                // FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::InnerAttributeUnstable`)
-                let msg = if is_macro {
-                    "inner macro attributes are unstable"
-                } else {
-                    "custom inner attributes are unstable"
-                };
-                feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit();
-            }
+                "custom inner attributes are unstable"
+            };
+            feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit();
         }
 
         if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)
diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs
index 22f5528248a32..03dff94350dad 100644
--- a/library/std/src/os/fd/raw.rs
+++ b/library/std/src/os/fd/raw.rs
@@ -19,11 +19,9 @@ use crate::sys_common::{AsInner, IntoInner};
 use crate::{fs, io};
 
 /// Raw file descriptors.
-#[rustc_allowed_through_unstable_modules]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg(not(target_os = "hermit"))]
 pub type RawFd = raw::c_int;
-#[rustc_allowed_through_unstable_modules]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg(target_os = "hermit")]
 pub type RawFd = i32;
@@ -33,7 +31,6 @@ pub type RawFd = i32;
 /// This is only available on unix and WASI platforms and must be imported in
 /// order to call the method. Windows platforms have a corresponding
 /// `AsRawHandle` and `AsRawSocket` set of traits.
-#[rustc_allowed_through_unstable_modules]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait AsRawFd {
     /// Extracts the raw file descriptor.
@@ -67,7 +64,6 @@ pub trait AsRawFd {
 
 /// A trait to express the ability to construct an object from a raw file
 /// descriptor.
-#[rustc_allowed_through_unstable_modules]
 #[stable(feature = "from_raw_os", since = "1.1.0")]
 pub trait FromRawFd {
     /// Constructs a new instance of `Self` from the given raw file
@@ -112,7 +108,6 @@ pub trait FromRawFd {
 
 /// A trait to express the ability to consume an object and acquire ownership of
 /// its raw file descriptor.
-#[rustc_allowed_through_unstable_modules]
 #[stable(feature = "into_raw_os", since = "1.4.0")]
 pub trait IntoRawFd {
     /// Consumes this object, returning the raw underlying file descriptor.
diff --git a/library/std/src/os/wasi/io/fd.rs b/library/std/src/os/wasi/io/fd.rs
deleted file mode 100644
index 930aca887e3c4..0000000000000
--- a/library/std/src/os/wasi/io/fd.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//! Owned and borrowed file descriptors.
-
-#![unstable(feature = "wasi_ext", issue = "71213")]
-
-// Tests for this module
-#[cfg(test)]
-mod tests;
-
-pub use crate::os::fd::owned::*;
diff --git a/library/std/src/os/wasi/io/mod.rs b/library/std/src/os/wasi/io/mod.rs
index 4e123a1eec8ae..5f9a735db085e 100644
--- a/library/std/src/os/wasi/io/mod.rs
+++ b/library/std/src/os/wasi/io/mod.rs
@@ -4,3 +4,7 @@
 
 #[stable(feature = "io_safety_wasi", since = "1.65.0")]
 pub use crate::os::fd::*;
+
+// Tests for this module
+#[cfg(test)]
+mod tests;
diff --git a/library/std/src/os/wasi/io/raw.rs b/library/std/src/os/wasi/io/raw.rs
deleted file mode 100644
index da3b36adad409..0000000000000
--- a/library/std/src/os/wasi/io/raw.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//! WASI-specific extensions to general I/O primitives.
-
-#![unstable(feature = "wasi_ext", issue = "71213")]
-
-// NOTE: despite the fact that this module is unstable,
-// stable Rust had the capability to access the stable
-// re-exported items from os::fd::raw through this
-// unstable module.
-// In PR #95956 the stability checker was changed to check
-// all path segments of an item rather than just the last,
-// which caused the aforementioned stable usage to regress
-// (see issue #99502).
-// As a result, the items in os::fd::raw were given the
-// rustc_allowed_through_unstable_modules attribute.
-// No regression tests were added to ensure this property,
-// as CI is not configured to test wasm32-wasi.
-// If this module is stabilized,
-// you may want to remove those attributes
-// (assuming no other unstable modules need them).
-pub use crate::os::fd::raw::*;
diff --git a/library/std/src/os/wasi/io/fd/tests.rs b/library/std/src/os/wasi/io/tests.rs
similarity index 100%
rename from library/std/src/os/wasi/io/fd/tests.rs
rename to library/std/src/os/wasi/io/tests.rs
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 384369b0012b5..3a22a16cb165e 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -32,9 +32,14 @@ use crate::{mem, panic, sys};
 // - nothing (so this macro is a no-op)
 macro_rules! rtprintpanic {
     ($($t:tt)*) => {
+        #[cfg(not(feature = "panic_immediate_abort"))]
         if let Some(mut out) = crate::sys::stdio::panic_output() {
             let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*));
         }
+        #[cfg(feature = "panic_immediate_abort")]
+        {
+            let _ = format_args!($($t)*);
+        }
     }
 }
 
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr
deleted file mode 100644
index f8672d755b959..0000000000000
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr
+++ /dev/null
@@ -1,169 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17
-   |
-LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
-   |                 ^^^^^^^^^^^^^    --------------- this expression has type `&Option<&Option<{integer}>>`
-   |                 |
-   |                 types differ in mutability
-   |
-   = note:      expected reference `&Option<{integer}>`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23
-   |
-LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
-   |                       ^^^^^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
-   |                       |
-   |                       expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27
-   |
-LL |         let _: &mut u32 = x;
-   |                --------   ^ types differ in mutability
-   |                |
-   |                expected due to this
-   |
-   = note: expected mutable reference `&mut u32`
-                      found reference `&{integer}`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23
-   |
-LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
-   |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
-   |                       |
-   |                       expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29
-   |
-LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
-   |                             ^^^^^^       ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
-   |                             |
-   |                             expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17
-   |
-LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
-   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
-   |                 |
-   |                 expected `Option<{integer}>`, found `&mut _`
-   |
-   = note:           expected enum `Option<{integer}>`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17
-   |
-LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
-   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
-   |                 |
-   |                 expected `Option<{integer}>`, found `&mut _`
-   |
-   = note:           expected enum `Option<{integer}>`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9
-   |
-LL |     let &mut _ = &&0;
-   |         ^^^^^^   --- this expression has type `&&{integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9
-   |
-LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
-   |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9
-   |
-LL |     let &mut _ = &&mut 0;
-   |         ^^^^^^   ------- this expression has type `&&mut {integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&mut {integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9
-   |
-LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
-   |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14
-   |
-LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
-   |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
-   |              |
-   |              types differ in mutability
-   |
-   = note:      expected reference `&&&&mut &&&mut &mut {integer}`
-           found mutable reference `&mut _`
-
-error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13
-   |
-LL |     let Foo(mut a) = &Foo(0);
-   |             ^^^^
-   |
-   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
-   = help: add `#![feature(mut_ref)]` 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]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13
-   |
-LL |     let Foo(mut a) = &mut Foo(0);
-   |             ^^^^
-   |
-   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
-   = help: add `#![feature(mut_ref)]` 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[E0277]: the trait bound `&_: main::Ref` is not satisfied
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14
-   |
-LL |     let &_ = generic();
-   |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
-   |
-   = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
-note: required by a bound in `generic`
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19
-   |
-LL |     fn generic<R: Ref>() -> R {
-   |                   ^^^ required by this bound in `generic`
-
-error: aborting due to 15 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/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr
deleted file mode 100644
index a37316b3097b0..0000000000000
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr
+++ /dev/null
@@ -1,199 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17
-   |
-LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
-   |                 ^^^^^
-   |
-   = note: cannot match inherited `&` with `&mut` pattern
-help: replace this `&mut` pattern with `&`
-   |
-LL |     if let Some(&Some(&_)) = &Some(&Some(0)) {
-   |                 ~
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23
-   |
-LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
-   |                       ^^^^^
-   |
-   = note: cannot match inherited `&` with `&mut` pattern
-help: replace this `&mut` pattern with `&`
-   |
-LL |     if let Some(&Some(&_)) = &Some(&mut Some(0)) {
-   |                       ~
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27
-   |
-LL |         let _: &mut u32 = x;
-   |                --------   ^ types differ in mutability
-   |                |
-   |                expected due to this
-   |
-   = note: expected mutable reference `&mut u32`
-                      found reference `&{integer}`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23
-   |
-LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
-   |                       ^^^^^
-   |
-   = note: cannot match inherited `&` with `&mut` pattern
-help: replace this `&mut` pattern with `&`
-   |
-LL |     if let Some(&Some(&_)) = &mut Some(&Some(0)) {
-   |                       ~
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29
-   |
-LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
-   |                             ^^^^^
-   |
-   = note: cannot match inherited `&` with `&mut` pattern
-help: replace this `&mut` pattern with `&`
-   |
-LL |     if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) {
-   |                             ~
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17
-   |
-LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
-   |                 ^^^^^
-   |
-   = note: cannot match inherited `&` with `&mut` pattern
-help: replace this `&mut` pattern with `&`
-   |
-LL |     if let Some(&Some(x)) = &Some(Some(0)) {
-   |                 ~
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17
-   |
-LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
-   |                 ^^^^^
-   |
-   = note: cannot match inherited `&` with `&mut` pattern
-help: replace this `&mut` pattern with `&`
-   |
-LL |     if let Some(&Some(x)) = &Some(Some(0)) {
-   |                 ~
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9
-   |
-LL |     let &mut _ = &&0;
-   |         ^^^^^^   --- this expression has type `&&{integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9
-   |
-LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
-   |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:37:17
-   |
-LL |     if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
-   |                 ^^^^^
-   |
-   = note: cannot match inherited `&` with `&mut` pattern
-help: replace this `&mut` pattern with `&`
-   |
-LL |     if let Some(&Some(&_)) = &Some(&mut Some(0)) {
-   |                 ~
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:41:22
-   |
-LL |     if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
-   |                      ^^^^^
-   |
-   = note: cannot match inherited `&` with `&mut` pattern
-help: replace this `&mut` pattern with `&`
-   |
-LL |     if let Some(Some(&x)) = &Some(Some(&mut 0)) {
-   |                      ~
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9
-   |
-LL |     let &mut _ = &&mut 0;
-   |         ^^^^^^   ------- this expression has type `&&mut {integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&mut {integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9
-   |
-LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
-   |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14
-   |
-LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
-   |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
-   |              |
-   |              types differ in mutability
-   |
-   = note:      expected reference `&&&&mut &&&mut &mut {integer}`
-           found mutable reference `&mut _`
-
-error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13
-   |
-LL |     let Foo(mut a) = &Foo(0);
-   |             ^^^^
-   |
-   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
-   = help: add `#![feature(mut_ref)]` 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]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13
-   |
-LL |     let Foo(mut a) = &mut Foo(0);
-   |             ^^^^
-   |
-   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
-   = help: add `#![feature(mut_ref)]` 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[E0277]: the trait bound `&_: main::Ref` is not satisfied
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14
-   |
-LL |     let &_ = generic();
-   |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
-   |
-   = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
-note: required by a bound in `generic`
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19
-   |
-LL |     fn generic<R: Ref>() -> R {
-   |                   ^^^ required by this bound in `generic`
-
-error: aborting due to 17 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/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
deleted file mode 100644
index fd616807b285c..0000000000000
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
+++ /dev/null
@@ -1,83 +0,0 @@
-//@ edition: 2024
-//@ revisions: classic structural both
-#![allow(incomplete_features)]
-#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))]
-#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))]
-
-pub fn main() {
-    if let Some(&mut Some(&_)) = &Some(&Some(0)) {
-        //~^ ERROR: mismatched types
-    }
-    if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
-        //~^ ERROR: mismatched types
-    }
-    if let Some(&Some(x)) = &mut Some(&Some(0)) {
-        let _: &mut u32 = x;
-        //~^ ERROR: mismatched types
-    }
-    if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
-        //~^ ERROR: mismatched types
-    }
-    if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
-        //~^ ERROR: mismatched types
-    }
-    if let Some(&mut Some(x)) = &Some(Some(0)) {
-        //~^ ERROR: mismatched types
-    }
-    if let Some(&mut Some(x)) = &Some(Some(0)) {
-        //~^ ERROR: mismatched types
-    }
-
-    let &mut _ = &&0;
-    //~^ ERROR: mismatched types
-
-    let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
-    //~^ ERROR: mismatched types
-
-    if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
-        //[classic]~^ ERROR: mismatched types
-    }
-
-    if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
-        //[classic]~^ ERROR: mismatched types
-    }
-
-    let &mut _ = &&mut 0;
-    //~^ ERROR: mismatched types
-
-    let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
-    //~^ ERROR: mismatched types
-
-    let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
-    //~^ ERROR: mismatched types
-
-    if let Some(&mut _) = &mut Some(&0) {
-        //[structural]~^ ERROR
-    }
-
-    struct Foo(u8);
-
-    let Foo(mut a) = &Foo(0);
-    //~^ ERROR: binding cannot be both mutable and by-reference
-    a = &42;
-
-    let Foo(mut a) = &mut Foo(0);
-    //~^ ERROR: binding cannot be both mutable and by-reference
-    a = &mut 42;
-
-    fn generic<R: Ref>() -> R {
-        R::meow()
-    }
-
-    trait Ref: Sized {
-        fn meow() -> Self;
-    }
-
-    impl Ref for &'static mut [(); 0] {
-        fn meow() -> Self {
-            &mut []
-        }
-    }
-
-    let &_ = generic(); //~ERROR: the trait bound `&_: main::Ref` is not satisfied [E0277]
-}
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr
deleted file mode 100644
index 2f62e9974fa3f..0000000000000
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr
+++ /dev/null
@@ -1,180 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17
-   |
-LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
-   |                 ^^^^^^^^^^^^^    --------------- this expression has type `&Option<&Option<{integer}>>`
-   |                 |
-   |                 types differ in mutability
-   |
-   = note:      expected reference `&Option<{integer}>`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23
-   |
-LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
-   |                       ^^^^^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
-   |                       |
-   |                       expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27
-   |
-LL |         let _: &mut u32 = x;
-   |                --------   ^ types differ in mutability
-   |                |
-   |                expected due to this
-   |
-   = note: expected mutable reference `&mut u32`
-                      found reference `&{integer}`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23
-   |
-LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
-   |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
-   |                       |
-   |                       expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29
-   |
-LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
-   |                             ^^^^^^       ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
-   |                             |
-   |                             expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17
-   |
-LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
-   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
-   |                 |
-   |                 expected `Option<{integer}>`, found `&mut _`
-   |
-   = note:           expected enum `Option<{integer}>`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17
-   |
-LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
-   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
-   |                 |
-   |                 expected `Option<{integer}>`, found `&mut _`
-   |
-   = note:           expected enum `Option<{integer}>`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9
-   |
-LL |     let &mut _ = &&0;
-   |         ^^^^^^   --- this expression has type `&&{integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9
-   |
-LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
-   |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9
-   |
-LL |     let &mut _ = &&mut 0;
-   |         ^^^^^^   ------- this expression has type `&&mut {integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&mut {integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9
-   |
-LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
-   |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
-   |         |
-   |         types differ in mutability
-   |
-   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14
-   |
-LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
-   |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
-   |              |
-   |              types differ in mutability
-   |
-   = note:      expected reference `&&&&mut &&&mut &mut {integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:54:17
-   |
-LL |     if let Some(&mut _) = &mut Some(&0) {
-   |                 ^^^^^^    ------------- this expression has type `&mut Option<&{integer}>`
-   |                 |
-   |                 types differ in mutability
-   |
-   = note:      expected reference `&{integer}`
-           found mutable reference `&mut _`
-
-error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13
-   |
-LL |     let Foo(mut a) = &Foo(0);
-   |             ^^^^
-   |
-   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
-   = help: add `#![feature(mut_ref)]` 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]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13
-   |
-LL |     let Foo(mut a) = &mut Foo(0);
-   |             ^^^^
-   |
-   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
-   = help: add `#![feature(mut_ref)]` 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[E0277]: the trait bound `&_: main::Ref` is not satisfied
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14
-   |
-LL |     let &_ = generic();
-   |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
-   |
-   = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
-note: required by a bound in `generic`
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19
-   |
-LL |     fn generic<R: Ref>() -> R {
-   |                   ^^^ required by this bound in `generic`
-
-error: aborting due to 16 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/pattern/no_ref_mut_behind_and.rs b/tests/ui/pattern/no_ref_mut_behind_and.rs
deleted file mode 100644
index c18d64904d035..0000000000000
--- a/tests/ui/pattern/no_ref_mut_behind_and.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ edition: 2021
-//@ run-pass
-#![allow(incomplete_features)]
-#![feature(ref_pat_eat_one_layer_2024)]
-
-fn main() {
-    let &[[x]] = &[&mut [42]];
-    let _: &i32 = x;
-}
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr
similarity index 88%
rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr
index a8b813941109c..c62461140750b 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr
@@ -1,5 +1,5 @@
 error[E0507]: cannot move out of a shared reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:6:29
+  --> $DIR/borrowck-errors.rs:9:29
    |
 LL |     if let Some(&Some(x)) = Some(&Some(&mut 0)) {
    |                       -     ^^^^^^^^^^^^^^^^^^^
@@ -14,7 +14,7 @@ LL +     if let Some(Some(x)) = Some(&Some(&mut 0)) {
    |
 
 error[E0596]: cannot borrow data in a `&` reference as mutable
-  --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:11:10
+  --> $DIR/borrowck-errors.rs:14:10
    |
 LL |     let &ref mut x = &0;
    |          ^^^^^^^^^ cannot borrow as mutable
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs
similarity index 54%
rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs
index 79403b1936528..a01e9ca265760 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs
@@ -1,6 +1,9 @@
 //@ edition: 2024
+//@ revisions: classic structural
+//! Tests for pattern errors not handled by the pattern typing rules, but by borrowck.
 #![allow(incomplete_features)]
-#![feature(ref_pat_eat_one_layer_2024)]
+#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
 
 pub fn main() {
     if let Some(&Some(x)) = Some(&Some(&mut 0)) {
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural.stderr
new file mode 100644
index 0000000000000..c62461140750b
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural.stderr
@@ -0,0 +1,25 @@
+error[E0507]: cannot move out of a shared reference
+  --> $DIR/borrowck-errors.rs:9:29
+   |
+LL |     if let Some(&Some(x)) = Some(&Some(&mut 0)) {
+   |                       -     ^^^^^^^^^^^^^^^^^^^
+   |                       |
+   |                       data moved here
+   |                       move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait
+   |
+help: consider removing the borrow
+   |
+LL -     if let Some(&Some(x)) = Some(&Some(&mut 0)) {
+LL +     if let Some(Some(x)) = Some(&Some(&mut 0)) {
+   |
+
+error[E0596]: cannot borrow data in a `&` reference as mutable
+  --> $DIR/borrowck-errors.rs:14:10
+   |
+LL |     let &ref mut x = &0;
+   |          ^^^^^^^^^ cannot borrow as mutable
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0507, E0596.
+For more information about an error, try `rustc --explain E0507`.
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic.stderr
new file mode 100644
index 0000000000000..89a52ba7d1ddb
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic.stderr
@@ -0,0 +1,58 @@
+error[E0308]: mismatched types
+  --> $DIR/cannot-mutably-deref-shared-ref.rs:9:9
+   |
+LL |     let &mut _ = &&0;
+   |         ^^^^^^   --- this expression has type `&&{integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/cannot-mutably-deref-shared-ref.rs:12:9
+   |
+LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
+   |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/cannot-mutably-deref-shared-ref.rs:15:9
+   |
+LL |     let &mut _ = &&mut 0;
+   |         ^^^^^^   ------- this expression has type `&&mut {integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/cannot-mutably-deref-shared-ref.rs:18:9
+   |
+LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
+   |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/cannot-mutably-deref-shared-ref.rs:21:14
+   |
+LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
+   |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
+   |              |
+   |              types differ in mutability
+   |
+   = note:      expected reference `&&&&mut &&&mut &mut {integer}`
+           found mutable reference `&mut _`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs
new file mode 100644
index 0000000000000..e22bd1f8f6c99
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs
@@ -0,0 +1,23 @@
+//@ edition: 2024
+//@ revisions: classic structural
+//! Test that `&mut` patterns don't match shared reference types under new typing rules in Rust 2024
+#![allow(incomplete_features)]
+#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
+
+pub fn main() {
+    let &mut _ = &&0;
+    //~^ ERROR: mismatched types
+
+    let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
+    //~^ ERROR: mismatched types
+
+    let &mut _ = &&mut 0;
+    //~^ ERROR: mismatched types
+
+    let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
+    //~^ ERROR: mismatched types
+
+    let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
+    //~^ ERROR: mismatched types
+}
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural.stderr
new file mode 100644
index 0000000000000..89a52ba7d1ddb
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural.stderr
@@ -0,0 +1,58 @@
+error[E0308]: mismatched types
+  --> $DIR/cannot-mutably-deref-shared-ref.rs:9:9
+   |
+LL |     let &mut _ = &&0;
+   |         ^^^^^^   --- this expression has type `&&{integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/cannot-mutably-deref-shared-ref.rs:12:9
+   |
+LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
+   |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/cannot-mutably-deref-shared-ref.rs:15:9
+   |
+LL |     let &mut _ = &&mut 0;
+   |         ^^^^^^   ------- this expression has type `&&mut {integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/cannot-mutably-deref-shared-ref.rs:18:9
+   |
+LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
+   |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/cannot-mutably-deref-shared-ref.rs:21:14
+   |
+LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
+   |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
+   |              |
+   |              types differ in mutability
+   |
+   = note:      expected reference `&&&&mut &&&mut &mut {integer}`
+           found mutable reference `&mut _`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/feature-gate-ref_pat_eat_one_layer_2024.rs
similarity index 100%
rename from tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/feature-gate-ref_pat_eat_one_layer_2024.rs
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/feature-gate-ref_pat_eat_one_layer_2024.stderr
similarity index 100%
rename from tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/feature-gate-ref_pat_eat_one_layer_2024.stderr
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic.stderr
new file mode 100644
index 0000000000000..43560a1803026
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic.stderr
@@ -0,0 +1,23 @@
+error[E0658]: binding cannot be both mutable and by-reference
+  --> $DIR/mut-ref-mut.rs:11:13
+   |
+LL |     let Foo(mut a) = &Foo(0);
+   |             ^^^^
+   |
+   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
+   = help: add `#![feature(mut_ref)]` 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]: binding cannot be both mutable and by-reference
+  --> $DIR/mut-ref-mut.rs:15:13
+   |
+LL |     let Foo(mut a) = &mut Foo(0);
+   |             ^^^^
+   |
+   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
+   = help: add `#![feature(mut_ref)]` 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
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs
new file mode 100644
index 0000000000000..786587984ba41
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs
@@ -0,0 +1,18 @@
+//@ edition: 2024
+//@ revisions: classic structural
+//! Test diagnostics for binding with `mut` when the default binding mode is by-ref.
+#![allow(incomplete_features)]
+#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
+
+pub fn main() {
+    struct Foo(u8);
+
+    let Foo(mut a) = &Foo(0);
+    //~^ ERROR: binding cannot be both mutable and by-reference
+    a = &42;
+
+    let Foo(mut a) = &mut Foo(0);
+    //~^ ERROR: binding cannot be both mutable and by-reference
+    a = &mut 42;
+}
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural.stderr
new file mode 100644
index 0000000000000..43560a1803026
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural.stderr
@@ -0,0 +1,23 @@
+error[E0658]: binding cannot be both mutable and by-reference
+  --> $DIR/mut-ref-mut.rs:11:13
+   |
+LL |     let Foo(mut a) = &Foo(0);
+   |             ^^^^
+   |
+   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
+   = help: add `#![feature(mut_ref)]` 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]: binding cannot be both mutable and by-reference
+  --> $DIR/mut-ref-mut.rs:15:13
+   |
+LL |     let Foo(mut a) = &mut Foo(0);
+   |             ^^^^
+   |
+   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
+   = help: add `#![feature(mut_ref)]` 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
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr
new file mode 100644
index 0000000000000..2bc3ecb7636d0
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr
@@ -0,0 +1,111 @@
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:15:17
+   |
+LL |     if let Some(&mut x) = &Some(&mut 0) {
+   |                 ^^^^^
+   |
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&x) = &Some(&mut 0) {
+   |                 ~
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:19:17
+   |
+LL |     if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
+   |                 ^^^^^
+   |
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(&x)) = &Some(&mut Some(0)) {
+   |                 ~
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:23:22
+   |
+LL |     if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
+   |                      ^^^^^
+   |
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(Some(&x)) = &Some(Some(&mut 0)) {
+   |                      ~
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:28:17
+   |
+LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
+   |                 ^^^^^
+   |
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(&_)) = &Some(&Some(0)) {
+   |                 ~
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:31:23
+   |
+LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
+   |                       ^^^^^
+   |
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(&_)) = &Some(&mut Some(0)) {
+   |                       ~
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:34:23
+   |
+LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
+   |                       ^^^^^
+   |
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(&_)) = &mut Some(&Some(0)) {
+   |                       ~
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:37:29
+   |
+LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
+   |                             ^^^^^
+   |
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) {
+   |                             ~
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:40:17
+   |
+LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
+   |                 ^^^^^
+   |
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(x)) = &Some(Some(0)) {
+   |                 ~
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:43:17
+   |
+LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
+   |                 ^^^^^
+   |
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(x)) = &Some(Some(0)) {
+   |                 ~
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs
new file mode 100644
index 0000000000000..3535ba9c7019a
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs
@@ -0,0 +1,46 @@
+//@ edition: 2024
+//@ revisions: classic structural
+//! Test cases for poorly-typed patterns in edition 2024 which are caught by HIR typeck. These must
+//! be separate from cases caught by MIR borrowck or the latter errors may not be emitted.
+#![allow(incomplete_features)]
+#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
+
+pub fn main() {
+    if let Some(&mut x) = &mut Some(&0) {
+        //[structural]~^ ERROR: mismatched types
+        let _: &u32 = x;
+    }
+
+    if let Some(&mut x) = &Some(&mut 0) {
+        //[classic]~^ ERROR: mismatched types
+        let _: &u32 = x;
+    }
+    if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
+        //[classic]~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
+        //[classic]~^ ERROR: mismatched types
+        let _: &u32 = x;
+    }
+
+    if let Some(&mut Some(&_)) = &Some(&Some(0)) {
+        //~^ ERROR: mismatched types
+    }
+    if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
+        //~^ ERROR: mismatched types
+    }
+    if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
+        //~^ ERROR: mismatched types
+    }
+    if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
+        //~^ ERROR: mismatched types
+    }
+    if let Some(&mut Some(x)) = &Some(Some(0)) {
+        //~^ ERROR: mismatched types
+    }
+    if let Some(&mut Some(x)) = &Some(Some(0)) {
+        //~^ ERROR: mismatched types
+    }
+}
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr
new file mode 100644
index 0000000000000..59d65553fae8f
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr
@@ -0,0 +1,89 @@
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:10:17
+   |
+LL |     if let Some(&mut x) = &mut Some(&0) {
+   |                 ^^^^^^    ------------- this expression has type `&mut Option<&{integer}>`
+   |                 |
+   |                 types differ in mutability
+   |
+   = note:      expected reference `&{integer}`
+           found mutable reference `&mut _`
+note: to declare a mutable binding use: `mut x`
+  --> $DIR/pattern-errors.rs:10:17
+   |
+LL |     if let Some(&mut x) = &mut Some(&0) {
+   |                 ^^^^^^
+help: consider removing `&mut` from the pattern
+   |
+LL |     if let Some(x) = &mut Some(&0) {
+   |                 ~
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:28:17
+   |
+LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
+   |                 ^^^^^^^^^^^^^    --------------- this expression has type `&Option<&Option<{integer}>>`
+   |                 |
+   |                 types differ in mutability
+   |
+   = note:      expected reference `&Option<{integer}>`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:31:23
+   |
+LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
+   |                       ^^^^^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
+   |                       |
+   |                       expected integer, found `&mut _`
+   |
+   = note:           expected type `{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:34:23
+   |
+LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
+   |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
+   |                       |
+   |                       expected integer, found `&mut _`
+   |
+   = note:           expected type `{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:37:29
+   |
+LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
+   |                             ^^^^^^       ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
+   |                             |
+   |                             expected integer, found `&mut _`
+   |
+   = note:           expected type `{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:40:17
+   |
+LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
+   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
+   |                 |
+   |                 expected `Option<{integer}>`, found `&mut _`
+   |
+   = note:           expected enum `Option<{integer}>`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/pattern-errors.rs:43:17
+   |
+LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
+   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
+   |                 |
+   |                 expected `Option<{integer}>`, found `&mut _`
+   |
+   = note:           expected enum `Option<{integer}>`
+           found mutable reference `&mut _`
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed
similarity index 73%
rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed
index e69d169966b52..4f4941975d804 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed
@@ -1,7 +1,11 @@
 //@ edition: 2024
 //@ run-rustfix
+//@ revisions: classic structural
+//! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts
+//! to bind by mutable reference.
 #![allow(incomplete_features)]
-#![feature(ref_pat_eat_one_layer_2024)]
+#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
 
 pub fn main() {
     if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) {
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr
similarity index 79%
rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr
index 8e135b65253fd..6c384a51fac14 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr
@@ -1,5 +1,5 @@
 error[E0596]: cannot borrow as mutable inside an `&` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:7:31
+  --> $DIR/ref-mut-inside-shared-ref-pat.rs:11:31
    |
 LL |     if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
    |                 -             ^
@@ -7,7 +7,7 @@ LL |     if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
    |                 help: replace this `&` with `&mut`: `&mut`
 
 error[E0596]: cannot borrow as mutable inside an `&` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:12:31
+  --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31
    |
 LL |     if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
    |            -                  ^
@@ -15,7 +15,7 @@ LL |     if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
    |            help: replace this `&` with `&mut`: `&mut`
 
 error[E0596]: cannot borrow as mutable inside an `&` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:20:15
+  --> $DIR/ref-mut-inside-shared-ref-pat.rs:24:15
    |
 LL |     let &pat!(x) = &mut 0;
    |         -     ^
@@ -23,7 +23,7 @@ LL |     let &pat!(x) = &mut 0;
    |         help: replace this `&` with `&mut`: `&mut`
 
 error[E0596]: cannot borrow as mutable inside an `&` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:24:19
+  --> $DIR/ref-mut-inside-shared-ref-pat.rs:28:19
    |
 LL |     let &(ref mut a, ref mut b) = &mut (true, false);
    |         -         ^
@@ -31,7 +31,7 @@ LL |     let &(ref mut a, ref mut b) = &mut (true, false);
    |         help: replace this `&` with `&mut`: `&mut`
 
 error[E0596]: cannot borrow as mutable inside an `&` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:24:30
+  --> $DIR/ref-mut-inside-shared-ref-pat.rs:28:30
    |
 LL |     let &(ref mut a, ref mut b) = &mut (true, false);
    |         -                    ^
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs
similarity index 73%
rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs
index a300cbcd4df52..b29bff7603f7a 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs
@@ -1,7 +1,11 @@
 //@ edition: 2024
 //@ run-rustfix
+//@ revisions: classic structural
+//! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts
+//! to bind by mutable reference.
 #![allow(incomplete_features)]
-#![feature(ref_pat_eat_one_layer_2024)]
+#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
 
 pub fn main() {
     if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed
new file mode 100644
index 0000000000000..4f4941975d804
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed
@@ -0,0 +1,33 @@
+//@ edition: 2024
+//@ run-rustfix
+//@ revisions: classic structural
+//! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts
+//! to bind by mutable reference.
+#![allow(incomplete_features)]
+#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
+
+pub fn main() {
+    if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) {
+        //~^ ERROR: cannot borrow as mutable inside an `&` pattern
+        let _: &mut u8 = x;
+    }
+
+    if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) {
+        //~^ ERROR: cannot borrow as mutable inside an `&` pattern
+        let _: &mut u8 = x;
+    }
+
+    macro_rules! pat {
+        ($var:ident) => { ref mut $var };
+    }
+    let &mut pat!(x) = &mut 0;
+    //~^ ERROR: cannot borrow as mutable inside an `&` pattern
+    let _: &mut u8 = x;
+
+    let &mut (ref mut a, ref mut b) = &mut (true, false);
+    //~^ ERROR: cannot borrow as mutable inside an `&` pattern
+    //~| ERROR: cannot borrow as mutable inside an `&` pattern
+    let _: &mut bool = a;
+    let _: &mut bool = b;
+}
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.stderr
new file mode 100644
index 0000000000000..6c384a51fac14
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.stderr
@@ -0,0 +1,43 @@
+error[E0596]: cannot borrow as mutable inside an `&` pattern
+  --> $DIR/ref-mut-inside-shared-ref-pat.rs:11:31
+   |
+LL |     if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
+   |                 -             ^
+   |                 |
+   |                 help: replace this `&` with `&mut`: `&mut`
+
+error[E0596]: cannot borrow as mutable inside an `&` pattern
+  --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31
+   |
+LL |     if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
+   |            -                  ^
+   |            |
+   |            help: replace this `&` with `&mut`: `&mut`
+
+error[E0596]: cannot borrow as mutable inside an `&` pattern
+  --> $DIR/ref-mut-inside-shared-ref-pat.rs:24:15
+   |
+LL |     let &pat!(x) = &mut 0;
+   |         -     ^
+   |         |
+   |         help: replace this `&` with `&mut`: `&mut`
+
+error[E0596]: cannot borrow as mutable inside an `&` pattern
+  --> $DIR/ref-mut-inside-shared-ref-pat.rs:28:19
+   |
+LL |     let &(ref mut a, ref mut b) = &mut (true, false);
+   |         -         ^
+   |         |
+   |         help: replace this `&` with `&mut`: `&mut`
+
+error[E0596]: cannot borrow as mutable inside an `&` pattern
+  --> $DIR/ref-mut-inside-shared-ref-pat.rs:28:30
+   |
+LL |     let &(ref mut a, ref mut b) = &mut (true, false);
+   |         -                    ^
+   |         |
+   |         help: replace this `&` with `&mut`: `&mut`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs
similarity index 54%
rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs
index afea249ffef0b..9372049a2b283 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs
@@ -1,9 +1,9 @@
 //@ run-pass
 //@ edition: 2021
-//@ revisions: classic structural both
+//@ revisions: classic structural
 #![allow(incomplete_features)]
-#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))]
-#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))]
+#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
 
 pub fn main() {
     if let &Some(Some(x)) = &Some(&mut Some(0)) {
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.rs
similarity index 100%
rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.rs
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.stderr
similarity index 100%
rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.stderr
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.rs
new file mode 100644
index 0000000000000..cb8fdb489c028
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.rs
@@ -0,0 +1,30 @@
+//@ edition: 2024
+//@ revisions: with_impl without_impl
+//@[with_impl] run-pass
+//! Sanity check that experimental new pattern typing rules work as expected with trait selection
+
+fn main() {
+    fn generic<R: Ref>() -> (R, bool) {
+        R::meow()
+    }
+
+    trait Ref: Sized {
+        fn meow() -> (Self, bool);
+    }
+
+    #[cfg(with_impl)]
+    impl Ref for &'static [(); 0] {
+        fn meow() -> (Self, bool) {
+            (&[], false)
+        }
+    }
+
+    impl Ref for &'static mut [(); 0] {
+        fn meow() -> (Self, bool) {
+            (&mut [], true)
+        }
+    }
+
+    let (&_, b) = generic(); //[without_impl]~ ERROR: the trait bound `&_: main::Ref` is not satisfied [E0277]
+    assert!(!b);
+}
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.without_impl.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.without_impl.stderr
new file mode 100644
index 0000000000000..83e45221facc7
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.without_impl.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `&_: main::Ref` is not satisfied
+  --> $DIR/trait-selection-sanity.rs:28:19
+   |
+LL |     let (&_, b) = generic();
+   |                   ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
+   |
+   = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
+note: required by a bound in `generic`
+  --> $DIR/trait-selection-sanity.rs:7:19
+   |
+LL |     fn generic<R: Ref>() -> (R, bool) {
+   |                   ^^^ required by this bound in `generic`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs
similarity index 62%
rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs
index b145446de0a1c..077b52d8f274e 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs
@@ -1,9 +1,11 @@
-//@ run-pass
 //@ edition: 2024
-//@ revisions: classic structural both
+//@ revisions: classic structural
+//@ run-pass
+//! Test cases for well-typed patterns in edition 2024. These are in their own file to ensure we
+//! pass both HIR typeck and MIR borrowck, as we may skip the latter if grouped with failing tests.
 #![allow(incomplete_features)]
-#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))]
-#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))]
+#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
 
 pub fn main() {
     if let Some(Some(&x)) = &Some(&Some(0)) {
@@ -54,35 +56,4 @@ pub fn main() {
     if let Some(&Some(x)) = &mut Some(Some(0)) {
         let _: u32 = x;
     }
-    #[cfg(any(classic, both))]
-    if let Some(&mut x) = &mut Some(&0) {
-        let _: &u32 = x;
-    }
-    #[cfg(any(structural, both))]
-    if let Some(&mut x) = &Some(&mut 0) {
-        let _: &u32 = x;
-    }
-
-    fn generic<R: Ref>() -> (R, bool) {
-        R::meow()
-    }
-
-    trait Ref: Sized {
-        fn meow() -> (Self, bool);
-    }
-
-    impl Ref for &'static [(); 0] {
-        fn meow() -> (Self, bool) {
-            (&[], false)
-        }
-    }
-
-    impl Ref for &'static mut [(); 0] {
-        fn meow() -> (Self, bool) {
-            (&mut [], true)
-        }
-    }
-
-    let (&_, b) = generic();
-    assert!(!b);
 }
diff --git a/tests/ui/proc-macro/inner-attr-non-inline-mod.rs b/tests/ui/proc-macro/inner-attr-non-inline-mod.rs
index 714463b622508..d4336a7f3e1e0 100644
--- a/tests/ui/proc-macro/inner-attr-non-inline-mod.rs
+++ b/tests/ui/proc-macro/inner-attr-non-inline-mod.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: -Z span-debug
 //@ error-pattern:custom inner attributes are unstable
 //@ error-pattern:inner macro attributes are unstable
-//@ error-pattern:this was previously accepted
 //@ proc-macro: test-macros.rs
 
 #![no_std] // Don't load unnecessary hygiene information from std
diff --git a/tests/ui/proc-macro/inner-attr-non-inline-mod.stderr b/tests/ui/proc-macro/inner-attr-non-inline-mod.stderr
index ccc967aaff971..025eec248188b 100644
--- a/tests/ui/proc-macro/inner-attr-non-inline-mod.stderr
+++ b/tests/ui/proc-macro/inner-attr-non-inline-mod.stderr
@@ -1,3 +1,13 @@
+error[E0658]: custom inner attributes are unstable
+  --> $DIR/module_with_attrs.rs:3:4
+   |
+LL | #![rustfmt::skip]
+   |    ^^^^^^^^^^^^^
+   |
+   = note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
+   = help: add `#![feature(custom_inner_attributes)]` 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]: inner macro attributes are unstable
   --> $DIR/module_with_attrs.rs:4:4
    |
@@ -9,7 +19,7 @@ LL | #![print_attr]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: non-inline modules in proc macro input are unstable
-  --> $DIR/inner-attr-non-inline-mod.rs:14:1
+  --> $DIR/inner-attr-non-inline-mod.rs:13:1
    |
 LL | mod module_with_attrs;
    | ^^^^^^^^^^^^^^^^^^^^^^
@@ -19,7 +29,7 @@ LL | mod module_with_attrs;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: custom inner attributes are unstable
-  --> $DIR/inner-attr-non-inline-mod.rs:14:1
+  --> $DIR/inner-attr-non-inline-mod.rs:13:1
    |
 LL | mod module_with_attrs;
    | ^^^^^^^^^^^^^^^^^^^^^^
@@ -28,27 +38,6 @@ LL | mod module_with_attrs;
    = help: add `#![feature(custom_inner_attributes)]` 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: custom inner attributes are unstable
-  --> $DIR/module_with_attrs.rs:3:4
-   |
-LL | #![rustfmt::skip]
-   |    ^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
-   = note: `#[deny(soft_unstable)]` on by default
-
 error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
-Future incompatibility report: Future breakage diagnostic:
-error: custom inner attributes are unstable
-  --> $DIR/module_with_attrs.rs:3:4
-   |
-LL | #![rustfmt::skip]
-   |    ^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
-   = note: `#[deny(soft_unstable)]` on by default
-
diff --git a/tests/ui/proc-macro/inner-attr-non-inline-mod.stdout b/tests/ui/proc-macro/inner-attr-non-inline-mod.stdout
index aaec40669e67e..450542f68c65c 100644
--- a/tests/ui/proc-macro/inner-attr-non-inline-mod.stdout
+++ b/tests/ui/proc-macro/inner-attr-non-inline-mod.stdout
@@ -4,35 +4,35 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
         spacing: Alone,
-        span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+        span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
     },
     Group {
         delimiter: Bracket,
         stream: TokenStream [
             Ident {
                 ident: "deny",
-                span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+                span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
             },
             Group {
                 delimiter: Parenthesis,
                 stream: TokenStream [
                     Ident {
                         ident: "unused_attributes",
-                        span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+                        span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
                     },
                 ],
-                span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+                span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
             },
         ],
-        span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+        span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
     },
     Ident {
         ident: "mod",
-        span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+        span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
     },
     Ident {
         ident: "module_with_attrs",
-        span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+        span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
     },
     Group {
         delimiter: Brace,
@@ -40,38 +40,38 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
             Punct {
                 ch: '#',
                 spacing: Joint,
-                span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+                span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
             },
             Punct {
                 ch: '!',
                 spacing: Alone,
-                span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+                span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
             },
             Group {
                 delimiter: Bracket,
                 stream: TokenStream [
                     Ident {
                         ident: "rustfmt",
-                        span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+                        span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
                     },
                     Punct {
                         ch: ':',
                         spacing: Joint,
-                        span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+                        span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
                     },
                     Punct {
                         ch: ':',
                         spacing: Alone,
-                        span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+                        span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
                     },
                     Ident {
                         ident: "skip",
-                        span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+                        span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
                     },
                 ],
-                span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+                span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
             },
         ],
-        span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0),
+        span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
     },
 ]
diff --git a/tests/ui/proc-macro/proc-macro-gates.rs b/tests/ui/proc-macro/proc-macro-gates.rs
index bf384bc479b51..04e097eb2f745 100644
--- a/tests/ui/proc-macro/proc-macro-gates.rs
+++ b/tests/ui/proc-macro/proc-macro-gates.rs
@@ -47,7 +47,6 @@ fn attrs() {
 
 fn test_case() {
     #![test] //~ ERROR inner macro attributes are unstable
-             //~| WARN this was previously accepted
 }
 
 fn main() {}
diff --git a/tests/ui/proc-macro/proc-macro-gates.stderr b/tests/ui/proc-macro/proc-macro-gates.stderr
index a05a7d0b185e6..3607b062a5fcb 100644
--- a/tests/ui/proc-macro/proc-macro-gates.stderr
+++ b/tests/ui/proc-macro/proc-macro-gates.stderr
@@ -84,27 +84,16 @@ LL |     let _x = #[identity_attr] println!();
    = help: add `#![feature(proc_macro_hygiene)]` 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: inner macro attributes are unstable
+error[E0658]: inner macro attributes are unstable
   --> $DIR/proc-macro-gates.rs:49:8
    |
 LL |     #![test]
    |        ^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
-   = note: `#[deny(soft_unstable)]` on by default
+   = note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
+   = help: add `#![feature(custom_inner_attributes)]` 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 10 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
-Future incompatibility report: Future breakage diagnostic:
-error: inner macro attributes are unstable
-  --> $DIR/proc-macro-gates.rs:49:8
-   |
-LL |     #![test]
-   |        ^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
-   = note: `#[deny(soft_unstable)]` on by default
-