Rollup merge of #135434 - dianne:match-2024-for-edition-2024, r=Nadrieril

Match Ergonomics 2024: update edition 2024 behavior of feature gates

This updates the edition 2024 behavior of the feature gates `ref_pat_eat_one_layer_2024_structural` and `ref_pat_eat_one_layer_2024` to correspond to the left and right typing rules compared [here](https://nadrieril.github.io/typing-rust-patterns/?compare=true&opts2=AQEBAAABAQABAgIAAQEBAAEBAAABAAA%3D&opts1=AQEBAgEBAQEBAgIAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=true&ty_d=3&style=SequentBindingMode), respectively. I'll implement the proposed new behavior for editions ≤ 2021 in another PR.

The tests are split up a bit awkwardly for practical reasons, but I've added new tests from 3 places:
- I got tests for where the typing rules differ from the "Compare" tab of the page linked above. These had to be split up based on where the errors are emitted and how rustfixable they are, so they've ended up in different files to keep tidy. Within each file, though, the order of the tests matches the order the typing differences appear in that comparison (as of when this was written).
- I used [this other comparison](https://nadrieril.github.io/typing-rust-patterns/?q=%5B%26mut+%26%28mut+x%29%5D%3A+%26mut+%5B%26CT%5D&compare=true&opts2=AQEBAgABAQEBAgIAAQEBAAEBAAABAAA%3D&opts1=AQEBAgEBAQEBAgIAAAAAAAAAAAAAAAA%3D&mode=compare&do_cmp=true&ty_d=3&style=SequentBindingMode) to test the `Deref(EatInner, FallbackToOuter)` rule of the left/"structural"/eat-inner ruleset. These are all in `well-typed-edition-2024.rs`.
- I added some select tests for cases where the new typing rules differ from current stable Rust. I had to be pickier about what I included here, but I tried to make sure each typing rule got some coverage. That said, my approach for these tests was a bit ad-hoc, so I may have missed something.

Relevant tracking issue: #123076

r? ````@ghost````
This commit is contained in:
Matthias Krüger 2025-01-30 12:45:18 +01:00 committed by GitHub
commit a3663577f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 1938 additions and 351 deletions

View file

@ -243,8 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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()
self.tcx.features().ref_pat_eat_one_layer_2024_structural()
}
/// Experimental pattern feature: when do reference patterns match against inherited references?
@ -435,7 +434,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
max_ref_mutbl: MutblCap,
) -> (Ty<'tcx>, ByRef, MutblCap) {
#[cfg(debug_assertions)]
if def_br == ByRef::Yes(Mutability::Mut) && max_ref_mutbl != MutblCap::Mut {
if def_br == ByRef::Yes(Mutability::Mut)
&& max_ref_mutbl != MutblCap::Mut
&& self.downgrade_mut_inside_shared()
{
span_bug!(pat.span, "Pattern mutability cap violated!");
}
match adjust_mode {
@ -2328,22 +2330,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;
@ -2352,28 +2339,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return expected;
}
InheritedRefMatchRule::EatInner => {
if let ty::Ref(_, _, r_mutbl) = *expected.kind() {
if let ty::Ref(_, _, r_mutbl) = *expected.kind()
&& pat_mutbl <= r_mutbl
{
// Match against the reference type; don't consume the inherited ref.
pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(r_mutbl);
// NB: The check for compatible pattern and ref type mutability assumes that
// `&` patterns can match against mutable references (RFC 3627, Rule 5). If
// we implement a pattern typing ruleset with Rule 4 (including the fallback
// to matching the inherited ref when the inner ref can't match) but not
// Rule 5, we'll need to check that here.
debug_assert!(ref_pat_matches_mut_ref);
// NB: For RFC 3627's Rule 3, we limit the default binding mode's ref
// mutability to `pat_info.max_ref_mutbl`. If we implement a pattern typing
// ruleset with Rule 4 but not Rule 3, we'll need to check that here.
debug_assert!(self.downgrade_mut_inside_shared());
let mutbl_cap = cmp::min(r_mutbl, pat_info.max_ref_mutbl.as_mutbl());
pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(mutbl_cap);
} else {
// The expected type isn't a reference, so match against the inherited ref.
// The reference pattern can't match against the expected type, so try
// matching against the inherited ref instead.
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 => {
@ -2447,6 +2444,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>],

View file

@ -0,0 +1,19 @@
# `ref_pat_eat_one_layer_2024_structural`
The tracking issue for this feature is: [#123076]
[#123076]: https://github.com/rust-lang/rust/issues/123076
---
This feature is incomplete and not yet intended for general use.
This implements experimental, Edition-dependent match ergonomics under consideration for inclusion
in Rust.
For more information, see the corresponding typing rules for [Editions 2024 and later].
On earlier Editions, the current behavior is unspecified.
For alternative experimental match ergonomics, see the feature
[`ref_pat_eat_one_layer_2024`](./ref-pat-eat-one-layer-2024.md).
[Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAgEBAQEBAgIAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=false

View file

@ -0,0 +1,19 @@
# `ref_pat_eat_one_layer_2024`
The tracking issue for this feature is: [#123076]
[#123076]: https://github.com/rust-lang/rust/issues/123076
---
This feature is incomplete and not yet intended for general use.
This implements experimental, Edition-dependent match ergonomics under consideration for inclusion
in Rust.
For more information, see the corresponding typing rules for [Editions 2024 and later].
On earlier Editions, the current behavior is unspecified.
For alternative experimental match ergonomics, see the feature
[`ref_pat_eat_one_layer_2024_structural`](./ref-pat-eat-one-layer-2024-structural.md).
[Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAAABAQABAgIAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false

View file

@ -0,0 +1,79 @@
error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array
--> $DIR/borrowck-errors.rs:13:16
|
LL | let [&x] = &[&mut 0];
| - ^^^^^^^^^ cannot move out of here
| |
| data moved here
| move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let [&ref x] = &[&mut 0];
| +++
error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array
--> $DIR/borrowck-errors.rs:19:16
|
LL | let [&x] = &mut [&mut 0];
| - ^^^^^^^^^^^^^ cannot move out of here
| |
| data moved here
| move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let [&ref x] = &mut [&mut 0];
| +++
error[E0507]: cannot move out of a shared reference
--> $DIR/borrowck-errors.rs:27: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:32:10
|
LL | let &ref mut x = &0;
| ^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/borrowck-errors.rs:35:23
|
LL | if let &Some(Some(x)) = &Some(&mut Some(0)) {
| ^ cannot borrow as mutable
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/borrowck-errors.rs:40:11
|
LL | let &[x] = &&mut [0];
| ^ cannot borrow as mutable
error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array
--> $DIR/borrowck-errors.rs:44:20
|
LL | let [&mut x] = &mut [&mut 0];
| - ^^^^^^^^^^^^^ cannot move out of here
| |
| data moved here
| move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let [&mut ref x] = &mut [&mut 0];
| +++
error: aborting due to 7 previous errors
Some errors have detailed explanations: E0507, E0508, E0596.
For more information about an error, try `rustc --explain E0507`.

View file

@ -1,9 +1,27 @@
//@ edition: 2024
//@ revisions: classic structural
//@ revisions: stable2021 classic2024 structural2024
//@[stable2021] edition: 2021
//@[classic2024] edition: 2024
//@[structural2024] edition: 2024
//! Tests for pattern errors not handled by the pattern typing rules, but by borrowck.
#![allow(incomplete_features)]
#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))]
/// These patterns additionally use `&` to match a `&mut` reference type, which causes compilation
/// to fail in HIR typeck on stable. As such, they need to be separate from the other tests.
fn errors_caught_in_hir_typeck_on_stable() {
let [&x] = &[&mut 0];
//[stable2021]~^ mismatched types
//[stable2021]~| types differ in mutability
//[classic2024]~^^^ ERROR: cannot move out of type
let _: &u32 = x;
let [&x] = &mut [&mut 0];
//[stable2021]~^ mismatched types
//[stable2021]~| types differ in mutability
//[classic2024]~^^^ ERROR: cannot move out of type
let _: &u32 = x;
}
pub fn main() {
if let Some(&Some(x)) = Some(&Some(&mut 0)) {
@ -13,4 +31,18 @@ pub fn main() {
let &ref mut x = &0;
//~^ cannot borrow data in a `&` reference as mutable [E0596]
if let &Some(Some(x)) = &Some(&mut Some(0)) {
//[stable2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable
let _: &u32 = x;
}
let &[x] = &&mut [0];
//[stable2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable
let _: &u32 = x;
let [&mut x] = &mut [&mut 0];
//[classic2024]~^ ERROR: cannot move out of type
#[cfg(stable2021)] let _: u32 = x;
#[cfg(structural2024)] let _: &mut u32 = x;
}

View file

@ -0,0 +1,69 @@
error[E0308]: mismatched types
--> $DIR/borrowck-errors.rs:13:10
|
LL | let [&x] = &[&mut 0];
| ^^ --------- this expression has type `&[&mut {integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL - let [&x] = &[&mut 0];
LL + let [x] = &[&mut 0];
|
error[E0308]: mismatched types
--> $DIR/borrowck-errors.rs:19:10
|
LL | let [&x] = &mut [&mut 0];
| ^^ ------------- this expression has type `&mut [&mut {integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL - let [&x] = &mut [&mut 0];
LL + let [x] = &mut [&mut 0];
|
error[E0507]: cannot move out of a shared reference
--> $DIR/borrowck-errors.rs:27: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:32:10
|
LL | let &ref mut x = &0;
| ^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/borrowck-errors.rs:35:23
|
LL | if let &Some(Some(x)) = &Some(&mut Some(0)) {
| ^ cannot borrow as mutable
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/borrowck-errors.rs:40:11
|
LL | let &[x] = &&mut [0];
| ^ cannot borrow as mutable
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0308, E0507, E0596.
For more information about an error, try `rustc --explain E0308`.

View file

@ -1,25 +0,0 @@
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`.

View file

@ -1,5 +1,5 @@
error[E0507]: cannot move out of a shared reference
--> $DIR/borrowck-errors.rs:9:29
--> $DIR/borrowck-errors.rs:27: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/borrowck-errors.rs:14:10
--> $DIR/borrowck-errors.rs:32:10
|
LL | let &ref mut x = &0;
| ^^^^^^^^^ cannot borrow as mutable

View file

@ -1,9 +1,9 @@
//@ edition: 2024
//@ revisions: classic structural
//@ revisions: classic2024 structural2024
//! 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))]
#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))]
pub fn main() {
let &mut _ = &&0;

View file

@ -1,5 +1,5 @@
error[E0658]: binding cannot be both mutable and by-reference
--> $DIR/mut-ref-mut.rs:11:13
--> $DIR/mut-ref-mut.rs:14:13
|
LL | let Foo(mut a) = &Foo(0);
| ^^^^
@ -9,7 +9,7 @@ LL | let Foo(mut a) = &Foo(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/mut-ref-mut.rs:15:13
--> $DIR/mut-ref-mut.rs:19:13
|
LL | let Foo(mut a) = &mut Foo(0);
| ^^^^
@ -18,6 +18,19 @@ LL | let Foo(mut a) = &mut Foo(0);
= 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
error[E0308]: mismatched types
--> $DIR/mut-ref-mut.rs:24:10
|
LL | let [&mut mut x] = &[&mut 0];
| ^^^^^
|
= note: cannot match inherited `&` with `&mut` pattern
help: replace this `&mut` pattern with `&`
|
LL | let [&mut x] = &[&mut 0];
| ~
For more information about this error, try `rustc --explain E0658`.
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0308, E0658.
For more information about an error, try `rustc --explain E0308`.

View file

@ -1,18 +1,29 @@
//@ edition: 2024
//@ revisions: classic structural
//@ revisions: stable2021 classic2024 structural2024
//@[stable2021] edition: 2021
//@[classic2024] edition: 2024
//@[structural2024] edition: 2024
//@[stable2021] run-pass
//! 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))]
#![allow(incomplete_features, unused_assignments, unused_variables)]
#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(structural2024, 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;
//[classic2024,structural2024]~^ ERROR: binding cannot be both mutable and by-reference
#[cfg(stable2021)] { a = 42 }
#[cfg(any(classic2024, structural2024))] { a = &42 }
let Foo(mut a) = &mut Foo(0);
//~^ ERROR: binding cannot be both mutable and by-reference
a = &mut 42;
//[classic2024,structural2024]~^ ERROR: binding cannot be both mutable and by-reference
#[cfg(stable2021)] { a = 42 }
#[cfg(any(classic2024, structural2024))] { a = &mut 42 }
let [&mut mut x] = &[&mut 0];
//[classic2024]~^ ERROR: mismatched types
//[classic2024]~| cannot match inherited `&` with `&mut` pattern
//[structural2024]~^^^ binding cannot be both mutable and by-reference
#[cfg(stable2021)] { x = 0 }
}

View file

@ -1,5 +1,5 @@
error[E0658]: binding cannot be both mutable and by-reference
--> $DIR/mut-ref-mut.rs:11:13
--> $DIR/mut-ref-mut.rs:14:13
|
LL | let Foo(mut a) = &Foo(0);
| ^^^^
@ -9,7 +9,7 @@ LL | let Foo(mut a) = &Foo(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/mut-ref-mut.rs:15:13
--> $DIR/mut-ref-mut.rs:19:13
|
LL | let Foo(mut a) = &mut Foo(0);
| ^^^^
@ -18,6 +18,16 @@ LL | let Foo(mut a) = &mut Foo(0);
= 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
error[E0658]: binding cannot be both mutable and by-reference
--> $DIR/mut-ref-mut.rs:24:15
|
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: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:15:17
--> $DIR/pattern-errors.rs:12:17
|
LL | if let Some(&mut x) = &Some(&mut 0) {
| ^^^^^
@ -11,7 +11,7 @@ LL | if let Some(&x) = &Some(&mut 0) {
| ~
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:19:17
--> $DIR/pattern-errors.rs:18:17
|
LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
| ^^^^^
@ -23,7 +23,7 @@ LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) {
| ~
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:23:22
--> $DIR/pattern-errors.rs:24:22
|
LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
| ^^^^^
@ -35,7 +35,7 @@ LL | if let Some(Some(&x)) = &Some(Some(&mut 0)) {
| ~
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:28:17
--> $DIR/pattern-errors.rs:31:17
|
LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) {
| ^^^^^
@ -47,19 +47,7 @@ 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
--> $DIR/pattern-errors.rs:41:23
|
LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
| ^^^^^
@ -71,19 +59,7 @@ 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
--> $DIR/pattern-errors.rs:51:17
|
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
| ^^^^^
@ -95,17 +71,53 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) {
| ~
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:43:17
--> $DIR/pattern-errors.rs:147:10
|
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
| ^^^^^
LL | let [&mut 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)) {
| ~
LL | let [&x] = &[&mut 0];
| ~
error: aborting due to 9 previous errors
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:153:10
|
LL | let [&mut &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:159:10
|
LL | let [&mut &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:165:10
|
LL | let [&mut &(mut x)] = &[&mut 0];
| ^^^^^
|
= note: cannot match inherited `&` with `&mut` pattern
help: replace this `&mut` pattern with `&`
|
LL | let [&&(mut x)] = &[&mut 0];
| ~
error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,46 +1,170 @@
//@ edition: 2024
//@ revisions: classic structural
//@ revisions: stable2021 classic2024 structural2024
//@[stable2021] edition: 2021
//@[classic2024] edition: 2024
//@[structural2024] edition: 2024
//! 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))]
#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(structural2024, 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;
//[classic2024]~^ ERROR: mismatched types
//[classic2024]~| cannot match inherited `&` with `&mut` pattern
#[cfg(stable2021)] let _: u32 = x;
#[cfg(structural2024)] let _: &u32 = x;
}
if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
//[classic]~^ ERROR: mismatched types
//[stable2021,classic2024]~^ ERROR: mismatched types
//[stable2021]~| expected integer, found `&_`
//[classic2024]~| cannot match inherited `&` with `&mut` pattern
let _: u32 = x;
}
if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
//[classic]~^ ERROR: mismatched types
let _: &u32 = x;
//[classic2024]~^ ERROR: mismatched types
//[classic2024]~| cannot match inherited `&` with `&mut` pattern
#[cfg(stable2021)] let _: u32 = x;
#[cfg(structural2024)] let _: &u32 = x;
}
if let Some(&mut Some(&_)) = &Some(&Some(0)) {
//~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern
}
if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
//~^ ERROR: mismatched types
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
}
if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
//~^ ERROR: mismatched types
//[stable2021]~| expected integer, found `&mut _`
//[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern
}
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(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) {
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_`
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
}
if let Some(&mut Some(x)) = &Some(Some(0)) {
//~^ ERROR: mismatched types
//[stable2021]~| expected `Option<{integer}>`, found `&mut _`
//[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern
}
}
fn structural_errors_0() {
let &[&mut x] = &&mut [0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| expected integer, found `&mut _`
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: u32 = x;
let &[&mut x] = &mut &mut [0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: u32 = x;
let &[&mut ref x] = &&mut [0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| expected integer, found `&mut _`
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: &u32 = x;
let &[&mut ref x] = &mut &mut [0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: &u32 = x;
let &[&mut mut x] = &&mut [0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| expected integer, found `&mut _`
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: u32 = x;
let &[&mut mut x] = &mut &mut [0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: u32 = x;
}
fn structural_errors_1() {
let [&(mut x)] = &[&0];
//[structural2024]~^ ERROR: binding cannot be both mutable and by-reference
#[cfg(stable2021)] let _: u32 = x;
#[cfg(classic2024)] let _: &u32 = x;
let [&(mut x)] = &mut [&0];
//[structural2024]~^ ERROR: binding cannot be both mutable and by-reference
#[cfg(stable2021)] let _: u32 = x;
#[cfg(classic2024)] let _: &u32 = x;
}
fn structural_errors_2() {
let [&&mut x] = &[&mut 0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: u32 = x;
let [&&mut x] = &mut [&mut 0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: u32 = x;
let [&&mut ref x] = &[&mut 0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: &u32 = x;
let [&&mut ref x] = &mut [&mut 0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: &u32 = x;
let [&&mut mut x] = &[&mut 0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: u32 = x;
let [&&mut mut x] = &mut [&mut 0];
//[stable2021,structural2024]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~| cannot match inherited `&` with `&mut` pattern
let _: u32 = x;
}
fn classic_errors_0() {
let [&mut x] = &[&mut 0];
//[classic2024]~^ ERROR: mismatched types
//[classic2024]~| cannot match inherited `&` with `&mut` pattern
#[cfg(stable2021)] let _: u32 = x;
#[cfg(structural2024)] let _: &u32 = x;
let [&mut &x] = &[&mut 0];
//[stable2021,classic2024]~^ ERROR: mismatched types
//[stable2021]~| expected integer, found `&_`
//[classic2024]~| cannot match inherited `&` with `&mut` pattern
let _: u32 = x;
let [&mut &ref x] = &[&mut 0];
//[stable2021,classic2024]~^ ERROR: mismatched types
//[stable2021]~| expected integer, found `&_`
//[classic2024]~| cannot match inherited `&` with `&mut` pattern
let _: &u32 = x;
let [&mut &(mut x)] = &[&mut 0];
//[stable2021,classic2024]~^ ERROR: mismatched types
//[stable2021]~| expected integer, found `&_`
//[classic2024]~| cannot match inherited `&` with `&mut` pattern
let _: u32 = x;
}

View file

@ -0,0 +1,283 @@
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:18:27
|
LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
| ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>`
| |
| expected integer, found `&_`
|
= note: expected type `{integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) {
| ~
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:31: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:36:17
|
LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
| ^^^^^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut Option<{integer}>`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:41: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:46:17
|
LL | if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) {
| ^^^^^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
| |
| expected `Option<&mut Option<{integer}>>`, found `&_`
|
= note: expected enum `Option<&mut Option<{integer}>>`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:51: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:59: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:59: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];
|
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:65:9
|
LL | let &[&mut x] = &mut &mut [0];
| ^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut &mut [{integer}; 1]`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:71: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:71: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];
|
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:77:9
|
LL | let &[&mut ref x] = &mut &mut [0];
| ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut &mut [{integer}; 1]`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:83: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:83: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[E0308]: mismatched types
--> $DIR/pattern-errors.rs:89:9
|
LL | let &[&mut mut x] = &mut &mut [0];
| ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut &mut [{integer}; 1]`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:109:10
|
LL | let [&&mut x] = &[&mut 0];
| ^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:115:10
|
LL | let [&&mut x] = &mut [&mut 0];
| ^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:121:10
|
LL | let [&&mut ref x] = &[&mut 0];
| ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:127:10
|
LL | let [&&mut ref x] = &mut [&mut 0];
| ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:133:10
|
LL | let [&&mut mut x] = &[&mut 0];
| ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:139:10
|
LL | let [&&mut mut x] = &mut [&mut 0];
| ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:153:15
|
LL | let [&mut &x] = &[&mut 0];
| ^^ --------- this expression has type `&[&mut {integer}; 1]`
| |
| expected integer, found `&_`
|
= note: expected type `{integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL - let [&mut &x] = &[&mut 0];
LL + let [&mut x] = &[&mut 0];
|
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:159:15
|
LL | let [&mut &ref x] = &[&mut 0];
| ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]`
| |
| expected integer, found `&_`
|
= note: expected type `{integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL - let [&mut &ref x] = &[&mut 0];
LL + let [&mut ref x] = &[&mut 0];
|
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:165:15
|
LL | let [&mut &(mut x)] = &[&mut 0];
| ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]`
| |
| expected integer, found `&_`
|
= note: expected type `{integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL - let [&mut &(mut x)] = &[&mut 0];
LL + let [&mut mut x)] = &[&mut 0];
|
error: aborting due to 21 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,89 +0,0 @@
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`.

View file

@ -0,0 +1,228 @@
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:31: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:36: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:41: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:46:28
|
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:51: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:59:11
|
LL | let &[&mut 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:65:11
|
LL | let &[&mut 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:71:11
|
LL | let &[&mut 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:77:11
|
LL | let &[&mut 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:83:11
|
LL | let &[&mut mut x] = &&mut [0];
| ^^^^^
|
= note: cannot match inherited `&` with `&mut` pattern
help: replace this `&mut` pattern with `&`
|
LL | let &[&mut x] = &&mut [0];
| ~
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:89:11
|
LL | let &[&mut mut x] = &mut &mut [0];
| ^^^^^
|
= note: cannot match inherited `&` with `&mut` pattern
help: replace this `&mut` pattern with `&`
|
LL | let &[&mut x] = &mut &mut [0];
| ~
error[E0658]: binding cannot be both mutable and by-reference
--> $DIR/pattern-errors.rs:97:12
|
LL | let [&(mut x)] = &[&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/pattern-errors.rs:102:12
|
LL | let [&(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:109:11
|
LL | let [&&mut 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:115:11
|
LL | let [&&mut 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:121:11
|
LL | let [&&mut 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:127:11
|
LL | let [&&mut 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:133:11
|
LL | let [&&mut mut x] = &[&mut 0];
| ^^^^^
|
= note: cannot match inherited `&` with `&mut` pattern
help: replace this `&mut` pattern with `&`
|
LL | let [&&mut x] = &[&mut 0];
| ~
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:139:11
|
LL | let [&&mut mut x] = &mut [&mut 0];
| ^^^^^
|
= note: cannot match inherited `&` with `&mut` pattern
help: replace this `&mut` pattern with `&`
|
LL | let [&&mut x] = &mut [&mut 0];
| ~
error: aborting due to 19 previous errors
Some errors have detailed explanations: E0308, E0658.
For more information about an error, try `rustc --explain E0308`.

View file

@ -0,0 +1,70 @@
error[E0308]: mismatched types
--> $DIR/ref-binding-on-inh-ref-errors.rs:60:10
|
LL | let [&mut ref x] = &[&mut 0];
| ^^^^^
|
= note: cannot match inherited `&` with `&mut` pattern
help: replace this `&mut` pattern with `&`
|
LL | let [&ref x] = &[&mut 0];
| ~
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:74:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &[ref mut x] = &[0];
| +
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/ref-binding-on-inh-ref-errors.rs:74:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^^^ cannot borrow as mutable
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:83:10
|
LL | let [ref x] = &[0];
| ^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &[ref x] = &[0];
| +
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:88:10
|
LL | let [ref x] = &mut [0];
| ^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &mut [ref x] = &mut [0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:93:10
|
LL | let [ref mut x] = &mut [0];
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &mut [ref mut x] = &mut [0];
| ++++
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0308, E0596.
For more information about an error, try `rustc --explain E0308`.

View file

@ -0,0 +1,97 @@
//@ revisions: stable2021 classic2024 structural2024
//@[stable2021] edition: 2021
//@[classic2024] edition: 2024
//@[structural2024] edition: 2024
//! Tests for errors from binding with `ref x` under a by-ref default binding mode in edition 2024.
//! These can't be in the same body as tests for other errors, since they're emitted during THIR
//! construction. The errors on stable edition 2021 Rust are unrelated.
#![allow(incomplete_features)]
#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))]
/// These only fail on the eat-inner variant of the new edition 2024 pattern typing rules.
/// The eat-outer variant eats the inherited reference, so binding with `ref` isn't a problem.
fn errors_from_eating_the_real_reference() {
let [&ref x] = &[&0];
//[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
#[cfg(stable2021)] let _: &u32 = x;
#[cfg(classic2024)] let _: &&u32 = x;
let [&ref x] = &mut [&0];
//[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
#[cfg(stable2021)] let _: &u32 = x;
#[cfg(classic2024)] let _: &&u32 = x;
let [&mut ref x] = &mut [&mut 0];
//[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
#[cfg(stable2021)] let _: &u32 = x;
#[cfg(classic2024)] let _: &&mut u32 = x;
let [&mut ref mut x] = &mut [&mut 0];
//[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
#[cfg(stable2021)] let _: &mut u32 = x;
#[cfg(classic2024)] let _: &mut &mut u32 = x;
}
/// To make absolutely sure binding with `ref` ignores inherited references on stable, let's
/// quarantine these typeck errors (from using a `&` pattern to match a `&mut` reference type).
fn errors_from_eating_the_real_reference_caught_in_hir_typeck_on_stable() {
let [&ref x] = &[&mut 0];
//[stable2021]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~^^^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
#[cfg(classic2024)] let _: &&mut u32 = x;
let [&ref x] = &mut [&mut 0];
//[stable2021]~^ ERROR: mismatched types
//[stable2021]~| types differ in mutability
//[structural2024]~^^^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
#[cfg(classic2024)] let _: &&mut u32 = x;
}
/// This one also needs to be quarantined for a typeck error on `classic2024` (eat-outer).
fn errors_dependent_on_eating_order_caught_in_hir_typeck_when_eating_outer() {
let [&mut ref x] = &[&mut 0];
//[classic2024]~^ ERROR: mismatched types
//[classic2024]~| cannot match inherited `&` with `&mut` pattern
//[structural2024]~^^^ ERROR: this pattern relies on behavior which may change in edition 2024
//[structural2024]~| cannot override to bind by-reference when that is the implicit default
#[cfg(stable2021)] let _: &u32 = x;
}
/// These should be errors in all editions. In edition 2024, they should be caught by the pattern
/// typing rules disallowing `ref` when there's an inherited reference. In old editions where that
/// resets the binding mode, they're borrowck errors due to binding with `ref mut`.
/// As a quirk of how the edition 2024 error is emitted during THIR construction, it ends up going
/// through borrowck as well, using the old `ref` behavior as a fallback, so we get that error too.
fn borrowck_errors_in_old_editions() {
let [ref mut x] = &[0];
//~^ ERROR: cannot borrow data in a `&` reference as mutable
//[classic2024,structural2024]~| ERROR: this pattern relies on behavior which may change in edition 2024
//[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default
}
/// The remaining tests are purely for testing `ref` bindings in the presence of an inherited
/// reference. These should always fail on edition 2024 and succeed on edition 2021.
pub fn main() {
let [ref x] = &[0];
//[classic2024,structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default
#[cfg(stable2021)] let _: &u32 = x;
let [ref x] = &mut [0];
//[classic2024,structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default
#[cfg(stable2021)] let _: &u32 = x;
let [ref mut x] = &mut [0];
//[classic2024,structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024
//[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default
#[cfg(stable2021)] let _: &mut u32 = x;
}

View file

@ -0,0 +1,42 @@
error[E0308]: mismatched types
--> $DIR/ref-binding-on-inh-ref-errors.rs:43:10
|
LL | let [&ref x] = &[&mut 0];
| ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL - let [&ref x] = &[&mut 0];
LL + let [ref x] = &[&mut 0];
|
error[E0308]: mismatched types
--> $DIR/ref-binding-on-inh-ref-errors.rs:50:10
|
LL | let [&ref x] = &mut [&mut 0];
| ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL - let [&ref x] = &mut [&mut 0];
LL + let [ref x] = &mut [&mut 0];
|
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/ref-binding-on-inh-ref-errors.rs:74:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^^^ cannot borrow as mutable
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0308, E0596.
For more information about an error, try `rustc --explain E0308`.

View file

@ -0,0 +1,141 @@
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:15:11
|
LL | let [&ref x] = &[&0];
| ^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &[&ref x] = &[&0];
| +
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:21:11
|
LL | let [&ref x] = &mut [&0];
| ^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &mut [&ref x] = &mut [&0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:27:15
|
LL | let [&mut ref x] = &mut [&mut 0];
| ^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &mut [&mut ref x] = &mut [&mut 0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:33:15
|
LL | let [&mut ref mut x] = &mut [&mut 0];
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &mut [&mut ref mut x] = &mut [&mut 0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:43:11
|
LL | let [&ref x] = &[&mut 0];
| ^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &[&ref x] = &[&mut 0];
| +
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:50:11
|
LL | let [&ref x] = &mut [&mut 0];
| ^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &mut [&ref x] = &mut [&mut 0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:60:15
|
LL | let [&mut ref x] = &[&mut 0];
| ^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &[&mut ref x] = &[&mut 0];
| +
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:74:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &[ref mut x] = &[0];
| +
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/ref-binding-on-inh-ref-errors.rs:74:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^^^ cannot borrow as mutable
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:83:10
|
LL | let [ref x] = &[0];
| ^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &[ref x] = &[0];
| +
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:88:10
|
LL | let [ref x] = &mut [0];
| ^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &mut [ref x] = &mut [0];
| ++++
error: this pattern relies on behavior which may change in edition 2024
--> $DIR/ref-binding-on-inh-ref-errors.rs:93:10
|
LL | let [ref mut x] = &mut [0];
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
|
LL | let &mut [ref mut x] = &mut [0];
| ++++
error: aborting due to 12 previous errors
For more information about this error, try `rustc --explain E0596`.

View file

@ -1,33 +0,0 @@
//@ 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;
}

View file

@ -0,0 +1,45 @@
//@ revisions: stable2021 classic2024 structural2024
//@[stable2021] edition: 2021
//@[classic2024] edition: 2024
//@[structural2024] edition: 2024
//@[classic2024] run-rustfix
//@[structural2024] run-rustfix
//! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts
//! to bind by mutable reference.
#![allow(incomplete_features)]
#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))]
pub fn main() {
if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) {
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
}
if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) {
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ 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;
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
let &mut (ref mut a, ref mut b) = &mut (true, false);
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
//[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut bool = a;
let _: &mut bool = b;
let &mut [x] = &mut &mut [0];
//[stable2021]~^ ERROR: mismatched types
//[classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &u32 = x;
}

View file

@ -1,5 +1,5 @@
error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref-mut-inside-shared-ref-pat.rs:11:31
--> $DIR/ref-mut-inside-shared-ref-pat.rs:14: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-mut-inside-shared-ref-pat.rs:16:31
--> $DIR/ref-mut-inside-shared-ref-pat.rs:20: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-mut-inside-shared-ref-pat.rs:24:15
--> $DIR/ref-mut-inside-shared-ref-pat.rs:29: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-mut-inside-shared-ref-pat.rs:28:19
--> $DIR/ref-mut-inside-shared-ref-pat.rs:34:19
|
LL | let &(ref mut a, ref mut b) = &mut (true, false);
| - ^
@ -31,13 +31,21 @@ 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
--> $DIR/ref-mut-inside-shared-ref-pat.rs:34: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
error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref-mut-inside-shared-ref-pat.rs:41:11
|
LL | let &[x] = &mut &mut [0];
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0596`.

View file

@ -1,20 +1,25 @@
//@ edition: 2024
//@ run-rustfix
//@ revisions: classic structural
//@ revisions: stable2021 classic2024 structural2024
//@[stable2021] edition: 2021
//@[classic2024] edition: 2024
//@[structural2024] edition: 2024
//@[classic2024] run-rustfix
//@[structural2024] run-rustfix
//! 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))]
#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))]
pub fn main() {
if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
}
if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
}
@ -22,12 +27,19 @@ pub fn main() {
($var:ident) => { ref mut $var };
}
let &pat!(x) = &mut 0;
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
let &(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
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
//[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut bool = a;
let _: &mut bool = b;
let &[x] = &mut &mut [0];
//[stable2021]~^ ERROR: mismatched types
//[classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &u32 = x;
}

View file

@ -0,0 +1,58 @@
error[E0308]: mismatched types
--> $DIR/ref-mut-inside-shared-ref-pat.rs:14:17
|
LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
| ^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option<Option<{integer}>>`
| |
| expected `Option<{integer}>`, found `&_`
|
= note: expected enum `Option<{integer}>`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/ref-mut-inside-shared-ref-pat.rs:20:12
|
LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
| ^^^^^^^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option<Option<{integer}>>`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut Option<Option<{integer}>>`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/ref-mut-inside-shared-ref-pat.rs:29:9
|
LL | let &pat!(x) = &mut 0;
| ^^^^^^^^ ------ this expression has type `&mut {integer}`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/ref-mut-inside-shared-ref-pat.rs:34:9
|
LL | let &(ref mut a, ref mut b) = &mut (true, false);
| ^^^^^^^^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut (bool, bool)`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut (bool, bool)`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/ref-mut-inside-shared-ref-pat.rs:41:9
|
LL | let &[x] = &mut &mut [0];
| ^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut &mut [{integer}; 1]`
found reference `&_`
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,33 +0,0 @@
//@ 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;
}

View file

@ -0,0 +1,45 @@
//@ revisions: stable2021 classic2024 structural2024
//@[stable2021] edition: 2021
//@[classic2024] edition: 2024
//@[structural2024] edition: 2024
//@[classic2024] run-rustfix
//@[structural2024] run-rustfix
//! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts
//! to bind by mutable reference.
#![allow(incomplete_features)]
#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))]
pub fn main() {
if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) {
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
}
if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) {
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ 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;
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut u8 = x;
let &mut (ref mut a, ref mut b) = &mut (true, false);
//[stable2021]~^ ERROR: mismatched types
//[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
//[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern
let _: &mut bool = a;
let _: &mut bool = b;
let &[x] = &mut &mut [0];
//[stable2021]~^ ERROR: mismatched types
//[classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern
let _: &u32 = x;
}

View file

@ -1,5 +1,5 @@
error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref-mut-inside-shared-ref-pat.rs:11:31
--> $DIR/ref-mut-inside-shared-ref-pat.rs:14: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-mut-inside-shared-ref-pat.rs:16:31
--> $DIR/ref-mut-inside-shared-ref-pat.rs:20: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-mut-inside-shared-ref-pat.rs:24:15
--> $DIR/ref-mut-inside-shared-ref-pat.rs:29: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-mut-inside-shared-ref-pat.rs:28:19
--> $DIR/ref-mut-inside-shared-ref-pat.rs:34: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-mut-inside-shared-ref-pat.rs:28:30
--> $DIR/ref-mut-inside-shared-ref-pat.rs:34:30
|
LL | let &(ref mut a, ref mut b) = &mut (true, false);
| - ^

View file

@ -6,9 +6,11 @@
#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
pub fn main() {
#[cfg(structural)]
if let &Some(Some(x)) = &Some(&mut Some(0)) {
let _: &u32 = x;
}
if let Some(&x) = Some(&mut 0) {
let _: u32 = x;
}

View file

@ -1,59 +1,127 @@
//@ edition: 2024
//@ revisions: classic structural
//@ run-pass
//@ revisions: stable2021 classic2024 structural2024
//@[stable2021] edition: 2021
//@[classic2024] edition: 2024
//@[structural2024] edition: 2024
//@[classic2024] run-pass
//@[structural2024] 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(classic, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
#![allow(incomplete_features, unused_mut)]
#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))]
pub fn main() {
if let Some(Some(&x)) = &Some(&Some(0)) {
let _: u32 = x;
}
if let Some(Some(&x)) = &Some(Some(&0)) {
let _: &u32 = x;
}
if let Some(Some(&&x)) = &Some(Some(&0)) {
let _: u32 = x;
}
if let Some(&Some(x)) = &Some(Some(0)) {
let _: u32 = x;
}
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
let _: u32 = x;
}
if let Some(Some(&x)) = &Some(&Some(0)) {
let _: u32 = x;
}
if let Some(&Some(&x)) = &mut Some(&Some(0)) {
let _: u32 = x;
}
if let Some(&Some(x)) = &mut Some(&Some(0)) {
let _: &u32 = x;
}
// Tests not using match ergonomics. These should always succeed with the same bindings.
if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) {
let _: &u32 = x;
}
if let &Some(Some(x)) = &Some(&mut Some(0)) {
let _: &u32 = x;
// Tests for differences in how many layers of reference are eaten by reference patterns
if let Some(Some(&x)) = &Some(Some(&0)) {
#[cfg(stable2021)] let _: u32 = x;
#[cfg(any(classic2024, structural2024))] let _: &u32 = x;
}
if let Some(&Some(&x)) = &Some(&mut Some(0)) {
if let Some(&Some(x)) = &mut Some(&Some(0)) {
// This additionally tests that `&` patterns can eat inherited `&mut` refs.
// This is possible on stable when the real reference being eaten is of a `&` type.
#[cfg(stable2021)] let _: u32 = x;
#[cfg(any(classic2024, structural2024))] let _: &u32 = x;
}
if let Some(Some(&&x)) = &Some(Some(&0)) {
//[stable2021]~^ mismatched types
//[stable2021]~| expected integer, found `&_`
let _: u32 = x;
}
if let Some(&Some(&x)) = &Some(&Some(0)) {
// Tests for eating a lone inherited reference
if let Some(Some(&x)) = &Some(&Some(0)) {
//[stable2021]~^ mismatched types
//[stable2021]~| expected integer, found `&_`
let _: u32 = x;
}
if let Some(&Some(&x)) = &Some(&mut Some(0)) {
if let Some(&Some(x)) = &Some(Some(0)) {
//[stable2021]~^ mismatched types
//[stable2021]~| expected `Option<{integer}>`, found `&_`
let _: u32 = x;
}
if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) {
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
//[stable2021]~^ mismatched types
//[stable2021]~| expected integer, found `&mut _`
let _: u32 = x;
}
// Tests for `&` patterns matching real `&mut` reference types
if let Some(&Some(&x)) = Some(&Some(&mut 0)) {
//[stable2021]~^ mismatched types
//[stable2021]~| types differ in mutability
let _: u32 = x;
}
// Tests for eating only one layer and also eating a lone inherited reference
if let Some(&Some(&x)) = &Some(&Some(0)) {
//[stable2021]~^ mismatched types
//[stable2021]~| expected integer, found `&_`
let _: u32 = x;
}
// Tests for `&` matching a lone inherited possibly-`&mut` reference
if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) {
//[stable2021]~^ mismatched types
//[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_`
let _: u32 = x;
}
if let Some(&Some(x)) = &mut Some(Some(0)) {
//[stable2021]~^ mismatched types
//[stable2021]~| expected `Option<{integer}>`, found `&_`
let _: u32 = x;
}
// Tests eating one layer, eating a lone inherited ref, and `&` eating `&mut` (realness varies)
if let Some(&Some(&x)) = &Some(&mut Some(0)) {
//[stable2021]~^ mismatched types
//[stable2021]~| types differ in mutability
let _: u32 = x;
}
if let Some(&Some(&x)) = &mut Some(&Some(0)) {
//[stable2021]~^ mismatched types
//[stable2021]~| expected integer, found `&_`
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)`:
let [&mut x] = &mut [&0];
//[stable2021]~^ mismatched types
//[stable2021]~| types differ in mutability
let _: &u32 = x;
let [&mut ref x] = &mut [&0];
//[stable2021]~^ mismatched types
//[stable2021]~| types differ in mutability
let _: &&u32 = x;
let [&mut ref mut x] = &mut [&0];
//[stable2021]~^ mismatched types
//[stable2021]~| types differ in mutability
let _: &mut &u32 = x;
let [&mut mut x] = &mut [&0];
//[stable2021]~^ mismatched types
//[stable2021]~| types differ in mutability
let _: &u32 = x;
let [&mut &x] = &mut [&0];
//[stable2021]~^ mismatched types
//[stable2021]~| types differ in mutability
let _: u32 = x;
let [&mut &ref x] = &mut [&0];
//[stable2021]~^ mismatched types
//[stable2021]~| types differ in mutability
let _: &u32 = x;
let [&mut &(mut x)] = &mut [&0];
//[stable2021]~^ mismatched types
//[stable2021]~| types differ in mutability
let _: u32 = x;
}

View file

@ -0,0 +1,260 @@
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:30:23
|
LL | if let Some(Some(&&x)) = &Some(Some(&0)) {
| ^^ --------------- this expression has type `&Option<Option<&{integer}>>`
| |
| expected integer, found `&_`
|
= note: expected type `{integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL - if let Some(Some(&&x)) = &Some(Some(&0)) {
LL + if let Some(Some(&x)) = &Some(Some(&0)) {
|
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:37:22
|
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
| |
| expected integer, found `&_`
|
= note: expected type `{integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL | if let Some(Some(x)) = &Some(&Some(0)) {
| ~
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:42:17
|
LL | if let Some(&Some(x)) = &Some(Some(0)) {
| ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
| |
| expected `Option<{integer}>`, found `&_`
|
= note: expected enum `Option<{integer}>`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:47:22
|
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
| ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
| |
| expected integer, found `&mut _`
|
= note: expected type `{integer}`
found mutable reference `&mut _`
note: to declare a mutable binding use: `mut x`
--> $DIR/well-typed-edition-2024.rs:47:22
|
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
| ^^^^^^
help: consider removing `&mut` from the pattern
|
LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) {
| ~
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:54:23
|
LL | if let Some(&Some(&x)) = Some(&Some(&mut 0)) {
| ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) {
| ~
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:61:23
|
LL | if let Some(&Some(&x)) = &Some(&Some(0)) {
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
| |
| expected integer, found `&_`
|
= note: expected type `{integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL | if let Some(&Some(x)) = &Some(&Some(0)) {
| ~
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:68:17
|
LL | if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) {
| ^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
| |
| expected `Option<&mut Option<{integer}>>`, found `&_`
|
= note: expected enum `Option<&mut Option<{integer}>>`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:73:17
|
LL | if let Some(&Some(x)) = &mut Some(Some(0)) {
| ^^^^^^^^ ------------------ this expression has type `&mut Option<Option<{integer}>>`
| |
| expected `Option<{integer}>`, found `&_`
|
= note: expected enum `Option<{integer}>`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:80:17
|
LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) {
| ^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut Option<{integer}>`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:85:23
|
LL | if let Some(&Some(&x)) = &mut Some(&Some(0)) {
| ^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>`
| |
| expected integer, found `&_`
|
= note: expected type `{integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL | if let Some(&Some(x)) = &mut Some(&Some(0)) {
| ~
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:93:10
|
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:93: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:98: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:98: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:103: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:103: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:108:10
|
LL | let [&mut 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 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[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:113:10
|
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 _`
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:118: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 _`
error[E0308]: mismatched types
--> $DIR/well-typed-edition-2024.rs:123:10
|
LL | let [&mut &(mut x)] = &mut [&0];
| ^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]`
| |
| types differ in mutability
|
= note: expected reference `&{integer}`
found mutable reference `&mut _`
error: aborting due to 17 previous errors
For more information about this error, try `rustc --explain E0308`.