about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs43
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr52
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs47
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr52
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr136
5 files changed, 151 insertions, 179 deletions
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 47175cda63b..be72af63fe5 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -235,6 +235,9 @@ enum InheritedRefMatchRule {
         /// Whether to allow reference patterns to consume only an inherited reference when matching
         /// against a non-reference type. This is `false` for stable Rust.
         eat_inherited_ref_alone: bool,
+        /// Whether to allow a `&mut` reference pattern to eat a `&` reference type if it's also
+        /// able to consume a mutable inherited reference. This is `false` for stable Rust.
+        fallback_to_outer: bool,
     },
 }
 
@@ -261,12 +264,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             } 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 { eat_inherited_ref_alone: false }
+                InheritedRefMatchRule::EatBoth {
+                    eat_inherited_ref_alone: false,
+                    fallback_to_outer: false,
+                }
             }
         } else {
+            let has_structural_gate = self.tcx.features().ref_pat_eat_one_layer_2024_structural();
             InheritedRefMatchRule::EatBoth {
-                eat_inherited_ref_alone: self.tcx.features().ref_pat_eat_one_layer_2024()
-                    || self.tcx.features().ref_pat_eat_one_layer_2024_structural(),
+                eat_inherited_ref_alone: has_structural_gate
+                    || self.tcx.features().ref_pat_eat_one_layer_2024(),
+                fallback_to_outer: has_structural_gate,
             }
         }
     }
@@ -2386,12 +2394,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         return expected;
                     }
                 }
-                InheritedRefMatchRule::EatBoth { eat_inherited_ref_alone: true } => {
+                InheritedRefMatchRule::EatBoth {
+                    eat_inherited_ref_alone: true,
+                    fallback_to_outer,
+                } => {
                     // Reset binding mode on old editions
                     pat_info.binding_mode = ByRef::No;
 
-                    if let ty::Ref(_, _, _) = *expected.kind() {
+                    if let ty::Ref(_, inner_ty, _) = *expected.kind() {
                         // Consume both the inherited and inner references.
+                        if fallback_to_outer && inh_mut.is_mut() {
+                            // If we can fall back to matching the inherited reference, the expected
+                            // type is a reference type (of any mutability), and the inherited
+                            // reference is mutable, we'll always be able to match. We handle that
+                            // here to avoid adding fallback-to-outer to the common logic below.
+                            // NB: This way of phrasing the logic will catch more cases than those
+                            // that need to fall back to matching the inherited reference. However,
+                            // as long as `&` patterns can match mutable (inherited) references
+                            // (RFC 3627, Rule 5) this should be sound.
+                            debug_assert!(ref_pat_matches_mut_ref);
+                            self.check_pat(inner, inner_ty, pat_info);
+                            return expected;
+                        } else {
+                            // Otherwise, use the common logic below for matching the inner
+                            // reference type.
+                        }
                     } else {
                         // The expected type isn't a reference type, so only match against the
                         // inherited reference.
@@ -2405,9 +2432,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         return expected;
                     }
                 }
-                InheritedRefMatchRule::EatBoth { eat_inherited_ref_alone: false } => {
+                rule @ InheritedRefMatchRule::EatBoth {
+                    eat_inherited_ref_alone: false,
+                    fallback_to_outer,
+                } => {
                     // Reset binding mode on stable Rust. This will be a type error below if
                     // `expected` is not a reference type.
+                    debug_assert!(!fallback_to_outer, "typing rule `{rule:?}` is unimplemented.");
                     pat_info.binding_mode = ByRef::No;
                     self.add_rust_2024_migration_desugared_pat(
                         pat_info.top_info.hir_id,
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr
index f784d7e9988..086d4bb133b 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr
@@ -105,28 +105,7 @@ LL +     let [ref x] = &mut [&0];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:108:10
-   |
-LL |     let [&mut ref mut x] = &mut [&0];
-   |          ^^^^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
-   |          |
-   |          types differ in mutability
-   |
-   = note:      expected reference `&{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:108:10
-   |
-LL |     let [&mut ref mut x] = &mut [&0];
-   |          ^^^^^^^^^^^^^^
-help: consider removing `&mut` from the pattern
-   |
-LL -     let [&mut ref mut x] = &mut [&0];
-LL +     let [ref mut x] = &mut [&0];
-   |
-
-error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:114:10
+  --> $DIR/well-typed-edition-2024.rs:117:10
    |
 LL |     let [&mut mut x] = &mut [&0];
    |          ^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -136,7 +115,7 @@ LL |     let [&mut mut x] = &mut [&0];
    = note:      expected reference `&{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:114:10
+  --> $DIR/well-typed-edition-2024.rs:117:10
    |
 LL |     let [&mut mut x] = &mut [&0];
    |          ^^^^^^^^^^
@@ -147,7 +126,7 @@ LL +     let [mut x] = &mut [&0];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:120:10
+  --> $DIR/well-typed-edition-2024.rs:123:10
    |
 LL |     let [&mut &x] = &mut [&0];
    |          ^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -158,7 +137,7 @@ LL |     let [&mut &x] = &mut [&0];
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:126:10
+  --> $DIR/well-typed-edition-2024.rs:129:10
    |
 LL |     let [&mut &ref x] = &mut [&0];
    |          ^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -169,7 +148,7 @@ LL |     let [&mut &ref x] = &mut [&0];
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:132:10
+  --> $DIR/well-typed-edition-2024.rs:135:10
    |
 LL |     let [&mut &(mut x)] = &mut [&0];
    |          ^^^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -179,6 +158,27 @@ LL |     let [&mut &(mut x)] = &mut [&0];
    = note:      expected reference `&{integer}`
            found mutable reference `&mut _`
 
+error[E0308]: mismatched types
+  --> $DIR/well-typed-edition-2024.rs:109:14
+   |
+LL |         let [&mut ref mut x] = &mut [&0];
+   |              ^^^^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
+   |              |
+   |              types differ in mutability
+   |
+   = note:      expected reference `&{integer}`
+           found mutable reference `&mut _`
+note: to declare a mutable binding use: `mut x`
+  --> $DIR/well-typed-edition-2024.rs:109:14
+   |
+LL |         let [&mut ref mut x] = &mut [&0];
+   |              ^^^^^^^^^^^^^^
+help: consider removing `&mut` from the pattern
+   |
+LL -         let [&mut ref mut x] = &mut [&0];
+LL +         let [ref mut x] = &mut [&0];
+   |
+
 error: aborting due to 11 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs
index 851011918fe..63a09fe90c9 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs
@@ -91,47 +91,50 @@ pub fn main() {
         #[cfg(any(classic2024, structural2024))] let _: u32 = x;
     }
 
-    // Tests for eat-inner rulesets matching on the outer reference if matching on the inner
-    // reference causes a mutability mismatch, i.e. `Deref(EatInner, FallbackToOuter)`:
+    // Tests for eat-inner and eat-both rulesets matching on the outer reference if matching on the
+    // inner reference causes a mutability mismatch. i.e. tests for "fallback-to-outer" deref rules.
     let [&mut x] = &mut [&0];
-    //[stable2021,classic2021,structural2021]~^ mismatched types
-    //[stable2021,classic2021,structural2021]~| types differ in mutability
-    // TODO: on `structural2021` `x` should have type `u32`
+    //[stable2021,classic2021]~^ mismatched types
+    //[stable2021,classic2021]~| types differ in mutability
+    #[cfg(structural2021)] let _: u32 = x;
     #[cfg(any(classic2024, structural2024))] let _: &u32 = x;
 
     let [&mut ref x] = &mut [&0];
-    //[stable2021,classic2021,structural2021]~^ mismatched types
-    //[stable2021,classic2021,structural2021]~| types differ in mutability
-    // TODO: on `structural2021` `x` should have type `&u32`
+    //[stable2021,classic2021]~^ mismatched types
+    //[stable2021,classic2021]~| types differ in mutability
+    #[cfg(structural2021)] let _: &u32 = x;
     #[cfg(any(classic2024, structural2024))] let _: &&u32 = x;
 
-    let [&mut ref mut x] = &mut [&0];
-    //[stable2021,classic2021,structural2021]~^ mismatched types
-    //[stable2021,classic2021,structural2021]~| types differ in mutability
-    // TODO: this should be a mut borrow behind shared borrow error on `structural2021`
-    #[cfg(any(classic2024, structural2024))] let _: &mut &u32 = x;
+    fn borrowck_error_on_structural2021() {
+        let [&mut ref mut x] = &mut [&0];
+        //[stable2021,classic2021]~^ mismatched types
+        //[stable2021,classic2021]~| types differ in mutability
+        //[structural2021]~^^^ cannot borrow data in a `&` reference as mutable
+        #[cfg(any(classic2024, structural2024))] let _: &mut &u32 = x;
+    }
+    borrowck_error_on_structural2021();
 
     let [&mut mut x] = &mut [&0];
-    //[stable2021,classic2021,structural2021]~^ mismatched types
-    //[stable2021,classic2021,structural2021]~| types differ in mutability
-    // TODO: on `structural2021` `x` should have type `u32`
+    //[stable2021,classic2021]~^ mismatched types
+    //[stable2021,classic2021]~| types differ in mutability
+    #[cfg(structural2021)] let _: u32 = x;
     #[cfg(any(classic2024, structural2024))] let _: &u32 = x;
 
     let [&mut &x] = &mut [&0];
     //[stable2021,classic2021,structural2021]~^ mismatched types
-    //[stable2021,classic2021,structural2021]~| types differ in mutability
-    // TODO: [structural2021]~| expected integer, found `&_`
+    //[stable2021,classic2021]~| types differ in mutability
+    //[structural2021]~| expected integer, found `&_`
     #[cfg(any(classic2024, structural2024))] let _: u32 = x;
 
     let [&mut &ref x] = &mut [&0];
     //[stable2021,classic2021,structural2021]~^ mismatched types
-    //[stable2021,classic2021,structural2021]~| types differ in mutability
-    // TODO: [structural2021]~| expected integer, found `&_`
+    //[stable2021,classic2021]~| types differ in mutability
+    //[structural2021]~| expected integer, found `&_`
     #[cfg(any(classic2024, structural2024))] let _: &u32 = x;
 
     let [&mut &(mut x)] = &mut [&0];
     //[stable2021,classic2021,structural2021]~^ mismatched types
-    //[stable2021,classic2021,structural2021]~| types differ in mutability
-    // TODO: [structural2021]~| expected integer, found `&_`
+    //[stable2021,classic2021]~| types differ in mutability
+    //[structural2021]~| expected integer, found `&_`
     #[cfg(any(classic2024, structural2024))] let _: u32 = x;
 }
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr
index fb99e3983e8..adb47172f34 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr
@@ -186,28 +186,7 @@ LL +     let [ref x] = &mut [&0];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:108:10
-   |
-LL |     let [&mut ref mut x] = &mut [&0];
-   |          ^^^^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
-   |          |
-   |          types differ in mutability
-   |
-   = note:      expected reference `&{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:108:10
-   |
-LL |     let [&mut ref mut x] = &mut [&0];
-   |          ^^^^^^^^^^^^^^
-help: consider removing `&mut` from the pattern
-   |
-LL -     let [&mut ref mut x] = &mut [&0];
-LL +     let [ref mut x] = &mut [&0];
-   |
-
-error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:114:10
+  --> $DIR/well-typed-edition-2024.rs:117:10
    |
 LL |     let [&mut mut x] = &mut [&0];
    |          ^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -217,7 +196,7 @@ LL |     let [&mut mut x] = &mut [&0];
    = note:      expected reference `&{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:114:10
+  --> $DIR/well-typed-edition-2024.rs:117:10
    |
 LL |     let [&mut mut x] = &mut [&0];
    |          ^^^^^^^^^^
@@ -228,7 +207,7 @@ LL +     let [mut x] = &mut [&0];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:120:10
+  --> $DIR/well-typed-edition-2024.rs:123:10
    |
 LL |     let [&mut &x] = &mut [&0];
    |          ^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -239,7 +218,7 @@ LL |     let [&mut &x] = &mut [&0];
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:126:10
+  --> $DIR/well-typed-edition-2024.rs:129:10
    |
 LL |     let [&mut &ref x] = &mut [&0];
    |          ^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -250,7 +229,7 @@ LL |     let [&mut &ref x] = &mut [&0];
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:132:10
+  --> $DIR/well-typed-edition-2024.rs:135:10
    |
 LL |     let [&mut &(mut x)] = &mut [&0];
    |          ^^^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -260,6 +239,27 @@ LL |     let [&mut &(mut x)] = &mut [&0];
    = note:      expected reference `&{integer}`
            found mutable reference `&mut _`
 
+error[E0308]: mismatched types
+  --> $DIR/well-typed-edition-2024.rs:109:14
+   |
+LL |         let [&mut ref mut x] = &mut [&0];
+   |              ^^^^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
+   |              |
+   |              types differ in mutability
+   |
+   = note:      expected reference `&{integer}`
+           found mutable reference `&mut _`
+note: to declare a mutable binding use: `mut x`
+  --> $DIR/well-typed-edition-2024.rs:109:14
+   |
+LL |         let [&mut ref mut x] = &mut [&0];
+   |              ^^^^^^^^^^^^^^
+help: consider removing `&mut` from the pattern
+   |
+LL -         let [&mut ref mut x] = &mut [&0];
+LL +         let [ref mut x] = &mut [&0];
+   |
+
 error: aborting due to 17 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr
index f784d7e9988..f8c2bd9a921 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr
@@ -63,122 +63,60 @@ LL +     if let Some(&Some(x)) = &mut Some(&Some(0)) {
    |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:96:10
+  --> $DIR/well-typed-edition-2024.rs:123:15
    |
-LL |     let [&mut x] = &mut [&0];
-   |          ^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
-   |          |
-   |          types differ in mutability
-   |
-   = note:      expected reference `&{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:96:10
-   |
-LL |     let [&mut x] = &mut [&0];
-   |          ^^^^^^
-help: consider removing `&mut` from the pattern
-   |
-LL -     let [&mut x] = &mut [&0];
-LL +     let [x] = &mut [&0];
-   |
-
-error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:102:10
-   |
-LL |     let [&mut ref x] = &mut [&0];
-   |          ^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
-   |          |
-   |          types differ in mutability
-   |
-   = note:      expected reference `&{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:102:10
-   |
-LL |     let [&mut ref x] = &mut [&0];
-   |          ^^^^^^^^^^
-help: consider removing `&mut` from the pattern
-   |
-LL -     let [&mut ref x] = &mut [&0];
-LL +     let [ref x] = &mut [&0];
-   |
-
-error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:108:10
-   |
-LL |     let [&mut ref mut x] = &mut [&0];
-   |          ^^^^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
-   |          |
-   |          types differ in mutability
-   |
-   = note:      expected reference `&{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:108:10
+LL |     let [&mut &x] = &mut [&0];
+   |               ^^    --------- this expression has type `&mut [&{integer}; 1]`
+   |               |
+   |               expected integer, found `&_`
    |
-LL |     let [&mut ref mut x] = &mut [&0];
-   |          ^^^^^^^^^^^^^^
-help: consider removing `&mut` from the pattern
+   = note:   expected type `{integer}`
+           found reference `&_`
+help: consider removing `&` from the pattern
    |
-LL -     let [&mut ref mut x] = &mut [&0];
-LL +     let [ref mut x] = &mut [&0];
+LL -     let [&mut &x] = &mut [&0];
+LL +     let [&mut x] = &mut [&0];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:114:10
-   |
-LL |     let [&mut mut x] = &mut [&0];
-   |          ^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
-   |          |
-   |          types differ in mutability
+  --> $DIR/well-typed-edition-2024.rs:129:15
    |
-   = note:      expected reference `&{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:114:10
+LL |     let [&mut &ref x] = &mut [&0];
+   |               ^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
+   |               |
+   |               expected integer, found `&_`
    |
-LL |     let [&mut mut x] = &mut [&0];
-   |          ^^^^^^^^^^
-help: consider removing `&mut` from the pattern
+   = note:   expected type `{integer}`
+           found reference `&_`
+help: consider removing `&` from the pattern
    |
-LL -     let [&mut mut x] = &mut [&0];
-LL +     let [mut x] = &mut [&0];
+LL -     let [&mut &ref x] = &mut [&0];
+LL +     let [&mut ref x] = &mut [&0];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:120:10
+  --> $DIR/well-typed-edition-2024.rs:135:15
    |
-LL |     let [&mut &x] = &mut [&0];
-   |          ^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
-   |          |
-   |          types differ in mutability
+LL |     let [&mut &(mut x)] = &mut [&0];
+   |               ^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
+   |               |
+   |               expected integer, found `&_`
    |
-   = note:      expected reference `&{integer}`
-           found mutable reference `&mut _`
-
-error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:126:10
+   = note:   expected type `{integer}`
+           found reference `&_`
+help: consider removing `&` from the pattern
    |
-LL |     let [&mut &ref x] = &mut [&0];
-   |          ^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
-   |          |
-   |          types differ in mutability
+LL -     let [&mut &(mut x)] = &mut [&0];
+LL +     let [&mut mut x)] = &mut [&0];
    |
-   = note:      expected reference `&{integer}`
-           found mutable reference `&mut _`
 
-error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:132:10
-   |
-LL |     let [&mut &(mut x)] = &mut [&0];
-   |          ^^^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
-   |          |
-   |          types differ in mutability
+error[E0596]: cannot borrow data in a `&` reference as mutable
+  --> $DIR/well-typed-edition-2024.rs:109:19
    |
-   = note:      expected reference `&{integer}`
-           found mutable reference `&mut _`
+LL |         let [&mut ref mut x] = &mut [&0];
+   |                   ^^^^^^^^^ cannot borrow as mutable
 
-error: aborting due to 11 previous errors
+error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0308, E0596.
+For more information about an error, try `rustc --explain E0308`.