about summary refs log tree commit diff
diff options
context:
space:
mode:
authordianne <diannes.gm@gmail.com>2025-01-05 19:42:26 -0800
committerdianne <diannes.gm@gmail.com>2025-01-20 16:03:37 -0800
commitf8315ae3b586fcd476e3dafd85b5891ddc70cc33 (patch)
treefba58d62dc7efc1b0901ca9d654d45348e4af656
parentc03769524bc52b0761385cab4b0a5c5e8fd96bd7 (diff)
downloadrust-f8315ae3b586fcd476e3dafd85b5891ddc70cc33.tar.gz
rust-f8315ae3b586fcd476e3dafd85b5891ddc70cc33.zip
"structural" ruleset: use the "classic" ruleset's diagnostic and fallback for inherited ref mutability mismatches
I think the diagnostic could use some work, but it's more helpful than
the alternative. The previous error was misleading, since it ignored the
inherited reference altogether.
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs58
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr8
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs30
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr437
4 files changed, 151 insertions, 382 deletions
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 1cbeb6d1fd0..ba5ba7a7452 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -2318,22 +2318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // (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();
+                        self.error_inherited_ref_mutability_mismatch(pat, pat_prefix_span);
                     }
 
                     pat_info.binding_mode = ByRef::No;
@@ -2353,22 +2338,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     } 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.
+                            // We can't match an inherited shared reference with `&mut`.
                             // 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()
-                                .skipped_ref_pats_mut()
-                                .insert(pat.hir_id);
-                            self.check_pat(inner, expected, pat_info);
-                            return expected;
+                            self.error_inherited_ref_mutability_mismatch(pat, pat_prefix_span);
                         }
+
+                        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::EatBoth => {
@@ -2442,6 +2423,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         Ty::new_ref(self.tcx, region, ty, mutbl)
     }
 
+    fn error_inherited_ref_mutability_mismatch(
+        &self,
+        pat: &'tcx Pat<'tcx>,
+        pat_prefix_span: Option<Span>,
+    ) -> ErrorGuaranteed {
+        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()
+    }
+
     fn try_resolve_slice_ty_to_array_ty(
         &self,
         before: &'tcx [Pat<'tcx>],
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
index 939eb4ea430..6993e724be2 100644
--- 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
@@ -83,7 +83,7 @@ LL |     if let Some(&Some(x)) = &Some(Some(0)) {
    |                 ~
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:125:10
+  --> $DIR/pattern-errors.rs:123:10
    |
 LL |     let [&mut x] = &[&mut 0];
    |          ^^^^^
@@ -95,7 +95,7 @@ LL |     let [&x] = &[&mut 0];
    |          ~
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:130:10
+  --> $DIR/pattern-errors.rs:128:10
    |
 LL |     let [&mut &x] = &[&mut 0];
    |          ^^^^^
@@ -107,7 +107,7 @@ LL |     let [&&x] = &[&mut 0];
    |          ~
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:135:10
+  --> $DIR/pattern-errors.rs:133:10
    |
 LL |     let [&mut &ref x] = &[&mut 0];
    |          ^^^^^
@@ -119,7 +119,7 @@ LL |     let [&&ref x] = &[&mut 0];
    |          ~
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:140:10
+  --> $DIR/pattern-errors.rs:138:10
    |
 LL |     let [&mut &(mut x)] = &[&mut 0];
    |          ^^^^^
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
index 90f77df871d..bbaa717e8bd 100644
--- 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
@@ -45,37 +45,36 @@ pub fn main() {
     }
 }
 
-// TODO: these should be mutability mismatches on `structural`
 fn structural_errors_0() {
     let &[&mut x] = &&mut [0];
     //[structural]~^ ERROR: mismatched types
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
     let _: u32 = x;
-    //[structural]~^ ERROR: mismatched types
 
     let &[&mut x] = &mut &mut [0];
     //[structural]~^ ERROR: mismatched types
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
     let _: u32 = x;
-    //[structural]~^ ERROR: mismatched types
 
     let &[&mut ref x] = &&mut [0];
     //[structural]~^ ERROR: mismatched types
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
     let _: &u32 = x;
 
     let &[&mut ref x] = &mut &mut [0];
     //[structural]~^ ERROR: mismatched types
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
     let _: &u32 = x;
 
     let &[&mut mut x] = &&mut [0];
     //[structural]~^ ERROR: mismatched types
-    //[structural]~| ERROR: binding cannot be both mutable and by-reference
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
     let _: u32 = x;
-    //[structural]~^ ERROR: mismatched types
 
     let &[&mut mut x] = &mut &mut [0];
     //[structural]~^ ERROR: mismatched types
-    //[structural]~| ERROR: binding cannot be both mutable and by-reference
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
     let _: u32 = x;
-    //[structural]~^ ERROR: mismatched types
 }
 
 fn structural_errors_1() {
@@ -88,37 +87,36 @@ fn structural_errors_1() {
     let _: &u32 = x;
 }
 
-// TODO: these should be mutability mismatches on `structural`
 fn structural_errors_2() {
     let [&&mut x] = &[&mut 0];
     //[structural]~^ ERROR: mismatched types
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
     let _: u32 = x;
-    //[structural]~^ ERROR: mismatched types
 
     let [&&mut x] = &mut [&mut 0];
     //[structural]~^ ERROR: mismatched types
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
     let _: u32 = x;
-    //[structural]~^ ERROR: mismatched types
 
     let [&&mut ref x] = &[&mut 0];
     //[structural]~^ ERROR: mismatched types
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
     let _: &u32 = x;
 
     let [&&mut ref x] = &mut [&mut 0];
     //[structural]~^ ERROR: mismatched types
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
     let _: &u32 = x;
 
     let [&&mut mut x] = &[&mut 0];
-    //[structural]~^ ERROR: binding cannot be both mutable and by-reference
-    //[structural]~| ERROR: mismatched types
-    let _: u32 = x;
     //[structural]~^ ERROR: mismatched types
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
+    let _: u32 = x;
 
     let [&&mut mut x] = &mut [&mut 0];
-    //[structural]~^ ERROR: binding cannot be both mutable and by-reference
-    //[structural]~| ERROR: mismatched types
-    let _: u32 = x;
     //[structural]~^ ERROR: mismatched types
+    //[structural]~| cannot match inherited `&` with `&mut` pattern
+    let _: u32 = x;
 }
 
 fn classic_errors_0() {
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
index ed7e09c937a..d835a3abe37 100644
--- 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
@@ -33,265 +33,136 @@ 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 _`
+   = 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)) {
-   |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
-   |                       |
-   |                       expected integer, found `&mut _`
+   |                       ^^^^^
    |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
+   = 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))) {
-   |                             ^^^^^^       ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
-   |                             |
-   |                             expected integer, found `&mut _`
+   |                             ^^^^^
    |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
+   = 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)) {
-   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
-   |                 |
-   |                 expected `Option<{integer}>`, found `&mut _`
+   |                 ^^^^^
    |
-   = note:           expected enum `Option<{integer}>`
-           found mutable reference `&mut _`
+   = 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)) {
-   |                 ^^^^^^^^^^^^    -------------- 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:50:11
+   |                 ^^^^^
    |
-LL |     let &[&mut x] = &&mut [0];
-   |           ^^^^^^    --------- this expression has type `&&mut [{integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/pattern-errors.rs:50:11
-   |
-LL |     let &[&mut x] = &&mut [0];
-   |           ^^^^^^
-help: consider removing `&mut` from the pattern
-   |
-LL -     let &[&mut x] = &&mut [0];
-LL +     let &[x] = &&mut [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:52:18
+  --> $DIR/pattern-errors.rs:49:11
    |
-LL |     let _: u32 = x;
-   |            ---   ^ expected `u32`, found `&_`
-   |            |
-   |            expected due to this
+LL |     let &[&mut x] = &&mut [0];
+   |           ^^^^^
    |
-   = note:   expected type `u32`
-           found reference `&_`
-help: consider dereferencing the borrow
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
-LL |     let _: u32 = *x;
-   |                  +
+LL |     let &[&x] = &&mut [0];
+   |           ~
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:55:11
-   |
-LL |     let &[&mut x] = &mut &mut [0];
-   |           ^^^^^^    ------------- this expression has type `&mut &mut [{integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/pattern-errors.rs:55:11
+  --> $DIR/pattern-errors.rs:54:11
    |
 LL |     let &[&mut x] = &mut &mut [0];
-   |           ^^^^^^
-help: consider removing `&mut` from the pattern
+   |           ^^^^^
    |
-LL -     let &[&mut x] = &mut &mut [0];
-LL +     let &[x] = &mut &mut [0];
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
+LL |     let &[&x] = &mut &mut [0];
+   |           ~
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:57:18
-   |
-LL |     let _: u32 = x;
-   |            ---   ^ expected `u32`, found `&_`
-   |            |
-   |            expected due to this
-   |
-   = note:   expected type `u32`
-           found reference `&_`
-help: consider dereferencing the borrow
-   |
-LL |     let _: u32 = *x;
-   |                  +
-
-error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:60:11
+  --> $DIR/pattern-errors.rs:59:11
    |
 LL |     let &[&mut ref x] = &&mut [0];
-   |           ^^^^^^^^^^    --------- this expression has type `&&mut [{integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
+   |           ^^^^^
    |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/pattern-errors.rs:60:11
-   |
-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];
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
+LL |     let &[&ref x] = &&mut [0];
+   |           ~
 
 error[E0308]: mismatched types
   --> $DIR/pattern-errors.rs:64:11
    |
 LL |     let &[&mut ref x] = &mut &mut [0];
-   |           ^^^^^^^^^^    ------------- this expression has type `&mut &mut [{integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/pattern-errors.rs:64:11
-   |
-LL |     let &[&mut ref x] = &mut &mut [0];
-   |           ^^^^^^^^^^
-help: consider removing `&mut` from the pattern
+   |           ^^^^^
    |
-LL -     let &[&mut ref x] = &mut &mut [0];
-LL +     let &[ref x] = &mut &mut [0];
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
+LL |     let &[&ref x] = &mut &mut [0];
+   |           ~
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:68:11
-   |
-LL |     let &[&mut mut x] = &&mut [0];
-   |           ^^^^^^^^^^    --------- this expression has type `&&mut [{integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/pattern-errors.rs:68:11
-   |
-LL |     let &[&mut mut x] = &&mut [0];
-   |           ^^^^^^^^^^
-help: consider removing `&mut` from the pattern
-   |
-LL -     let &[&mut mut x] = &&mut [0];
-LL +     let &[mut x] = &&mut [0];
-   |
-
-error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/pattern-errors.rs:68:16
+  --> $DIR/pattern-errors.rs:69:11
    |
 LL |     let &[&mut mut x] = &&mut [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[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:71:18
+   |           ^^^^^
    |
-LL |     let _: u32 = x;
-   |            ---   ^ expected `u32`, found `&_`
-   |            |
-   |            expected due to this
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
-   = note:   expected type `u32`
-           found reference `&_`
-help: consider dereferencing the borrow
-   |
-LL |     let _: u32 = *x;
-   |                  +
+LL |     let &[&mut x] = &&mut [0];
+   |           ~
 
 error[E0308]: mismatched types
   --> $DIR/pattern-errors.rs:74:11
    |
 LL |     let &[&mut mut x] = &mut &mut [0];
-   |           ^^^^^^^^^^    ------------- this expression has type `&mut &mut [{integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/pattern-errors.rs:74:11
-   |
-LL |     let &[&mut mut x] = &mut &mut [0];
-   |           ^^^^^^^^^^
-help: consider removing `&mut` from the pattern
-   |
-LL -     let &[&mut mut x] = &mut &mut [0];
-LL +     let &[mut x] = &mut &mut [0];
-   |
-
-error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/pattern-errors.rs:74:16
+   |           ^^^^^
    |
-LL |     let &[&mut mut x] = &mut &mut [0];
-   |                ^^^^
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
-   = 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[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:77:18
-   |
-LL |     let _: u32 = x;
-   |            ---   ^ expected `u32`, found `&_`
-   |            |
-   |            expected due to this
-   |
-   = note:   expected type `u32`
-           found reference `&_`
-help: consider dereferencing the borrow
-   |
-LL |     let _: u32 = *x;
-   |                  +
+LL |     let &[&mut x] = &mut &mut [0];
+   |           ~
 
 error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/pattern-errors.rs:82:12
+  --> $DIR/pattern-errors.rs:81:12
    |
 LL |     let [&(mut x)] = &[&0];
    |            ^^^^
@@ -301,7 +172,7 @@ LL |     let [&(mut x)] = &[&0];
    = 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/pattern-errors.rs:86:12
+  --> $DIR/pattern-errors.rs:85:12
    |
 LL |     let [&(mut x)] = &mut [&0];
    |            ^^^^
@@ -311,182 +182,78 @@ LL |     let [&(mut x)] = &mut [&0];
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:93:11
+  --> $DIR/pattern-errors.rs:91:11
    |
 LL |     let [&&mut x] = &[&mut 0];
-   |           ^^^^^^    --------- this expression has type `&[&mut {integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
+   |           ^^^^^
    |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-help: consider removing `&mut` from the pattern
-   |
-LL -     let [&&mut x] = &[&mut 0];
-LL +     let [&x] = &[&mut 0];
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
+LL |     let [&&x] = &[&mut 0];
+   |           ~
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:95:18
-   |
-LL |     let _: u32 = x;
-   |            ---   ^ expected `u32`, found `&_`
-   |            |
-   |            expected due to this
-   |
-   = note:   expected type `u32`
-           found reference `&_`
-help: consider dereferencing the borrow
-   |
-LL |     let _: u32 = *x;
-   |                  +
-
-error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:98:11
+  --> $DIR/pattern-errors.rs:96:11
    |
 LL |     let [&&mut x] = &mut [&mut 0];
-   |           ^^^^^^    ------------- this expression has type `&mut [&mut {integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-help: consider removing `&mut` from the pattern
+   |           ^^^^^
    |
-LL -     let [&&mut x] = &mut [&mut 0];
-LL +     let [&x] = &mut [&mut 0];
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
+LL |     let [&&x] = &mut [&mut 0];
+   |           ~
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:100:18
-   |
-LL |     let _: u32 = x;
-   |            ---   ^ expected `u32`, found `&_`
-   |            |
-   |            expected due to this
-   |
-   = note:   expected type `u32`
-           found reference `&_`
-help: consider dereferencing the borrow
-   |
-LL |     let _: u32 = *x;
-   |                  +
-
-error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:103:11
+  --> $DIR/pattern-errors.rs:101:11
    |
 LL |     let [&&mut ref x] = &[&mut 0];
-   |           ^^^^^^^^^^    --------- this expression has type `&[&mut {integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
+   |           ^^^^^
    |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-help: consider removing `&mut` from the pattern
-   |
-LL -     let [&&mut ref x] = &[&mut 0];
-LL +     let [&ref x] = &[&mut 0];
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
+LL |     let [&&ref x] = &[&mut 0];
+   |           ~
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:107:11
+  --> $DIR/pattern-errors.rs:106:11
    |
 LL |     let [&&mut ref x] = &mut [&mut 0];
-   |           ^^^^^^^^^^    ------------- this expression has type `&mut [&mut {integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
+   |           ^^^^^
    |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-help: consider removing `&mut` from the pattern
-   |
-LL -     let [&&mut ref x] = &mut [&mut 0];
-LL +     let [&ref x] = &mut [&mut 0];
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
+LL |     let [&&ref x] = &mut [&mut 0];
+   |           ~
 
 error[E0308]: mismatched types
   --> $DIR/pattern-errors.rs:111:11
    |
 LL |     let [&&mut mut x] = &[&mut 0];
-   |           ^^^^^^^^^^    --------- this expression has type `&[&mut {integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-help: consider removing `&mut` from the pattern
-   |
-LL -     let [&&mut mut x] = &[&mut 0];
-LL +     let [&mut x] = &[&mut 0];
-   |
-
-error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/pattern-errors.rs:111:16
-   |
-LL |     let [&&mut mut x] = &[&mut 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[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:114:18
-   |
-LL |     let _: u32 = x;
-   |            ---   ^ expected `u32`, found `&_`
-   |            |
-   |            expected due to this
+   |           ^^^^^
    |
-   = note:   expected type `u32`
-           found reference `&_`
-help: consider dereferencing the borrow
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
-LL |     let _: u32 = *x;
-   |                  +
+LL |     let [&&mut x] = &[&mut 0];
+   |           ~
 
 error[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:117:11
-   |
-LL |     let [&&mut mut x] = &mut [&mut 0];
-   |           ^^^^^^^^^^    ------------- this expression has type `&mut [&mut {integer}; 1]`
-   |           |
-   |           expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-help: consider removing `&mut` from the pattern
-   |
-LL -     let [&&mut mut x] = &mut [&mut 0];
-LL +     let [&mut x] = &mut [&mut 0];
-   |
-
-error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/pattern-errors.rs:117:16
+  --> $DIR/pattern-errors.rs:116:11
    |
 LL |     let [&&mut mut x] = &mut [&mut 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[E0308]: mismatched types
-  --> $DIR/pattern-errors.rs:120:18
-   |
-LL |     let _: u32 = x;
-   |            ---   ^ expected `u32`, found `&_`
-   |            |
-   |            expected due to this
+   = note: cannot match inherited `&` with `&mut` pattern
+help: replace this `&mut` pattern with `&`
    |
-   = note:   expected type `u32`
-           found reference `&_`
-help: consider dereferencing the borrow
-   |
-LL |     let _: u32 = *x;
-   |                  +
+LL |     let [&&mut x] = &mut [&mut 0];
+   |           ~
 
-error: aborting due to 33 previous errors
+error: aborting due to 21 previous errors
 
 Some errors have detailed explanations: E0308, E0658.
 For more information about an error, try `rustc --explain E0308`.