diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2025-01-30 12:45:18 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-30 12:45:18 +0100 |
| commit | a3663577f298e08520c1407f6d8944aa4200b99c (patch) | |
| tree | 6b0c0d608668256a41154793c3f517c266f5e546 /tests | |
| parent | 282d8660deb77f3812c892db6784ac55cc8e51df (diff) | |
| parent | be7d6e3d5e34641f99f4a77d143beefbf243a934 (diff) | |
| download | rust-a3663577f298e08520c1407f6d8944aa4200b99c.tar.gz rust-a3663577f298e08520c1407f6d8944aa4200b99c.zip | |
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````
Diffstat (limited to 'tests')
31 files changed, 1832 insertions, 303 deletions
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr new file mode 100644 index 00000000000..331b86736a0 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr @@ -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`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs index a01e9ca2657..3f5d9c8db5d 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs @@ -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; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr new file mode 100644 index 00000000000..65c98e2da9c --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr @@ -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`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural.stderr deleted file mode 100644 index c6246114075..00000000000 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural.stderr +++ /dev/null @@ -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`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr index c6246114075..30d2f9f3d70 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr @@ -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 diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic2024.stderr index 89a52ba7d1d..89a52ba7d1d 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic2024.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs index e22bd1f8f6c..a493b672c92 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs @@ -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; diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural2024.stderr index 89a52ba7d1d..89a52ba7d1d 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural2024.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr index 43560a18030..afaa925a757 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr @@ -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]; + | ~ + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs index 786587984ba..fbd6514df73 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs @@ -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 } } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr index 43560a18030..fd82da70a18 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr @@ -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`. 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.classic2024.stderr index 2bc3ecb7636..3a124dcead5 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.classic2024.stderr @@ -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,65 +47,77 @@ LL | if let Some(&Some(&_)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:31:23 + --> $DIR/pattern-errors.rs:41:23 | -LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { +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(&_)) = &Some(&mut Some(0)) { +LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:34:23 + --> $DIR/pattern-errors.rs:51:17 | -LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { - | ^^^^^ +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(&_)) = &mut Some(&Some(0)) { - | ~ +LL | if let Some(&Some(x)) = &Some(Some(0)) { + | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:37:29 + --> $DIR/pattern-errors.rs:147:10 | -LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut 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(Some((&_)))) = &Some(Some(&mut Some(0))) { - | ~ +LL | let [&x] = &[&mut 0]; + | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:40:17 + --> $DIR/pattern-errors.rs:153: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[E0308]: mismatched types - --> $DIR/pattern-errors.rs:43:17 + --> $DIR/pattern-errors.rs:159:10 | -LL | if let Some(&mut Some(x)) = &Some(Some(0)) { - | ^^^^^ +LL | let [&mut &ref 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 [&&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 9 previous errors +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs index 3535ba9c701..c07c2972cd0 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 @@ -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; +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr new file mode 100644 index 00000000000..e7eb1813846 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr @@ -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`. 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 deleted file mode 100644 index 59d65553fae..00000000000 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr +++ /dev/null @@ -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`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr new file mode 100644 index 00000000000..861ed2216cd --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr @@ -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`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr new file mode 100644 index 00000000000..70cdcbd62eb --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -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`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs new file mode 100644 index 00000000000..4c88c0c63ae --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs @@ -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; +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr new file mode 100644 index 00000000000..a21e4bb5b8f --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr @@ -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`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr new file mode 100644 index 00000000000..ee2c831bfcc --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr @@ -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`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed deleted file mode 100644 index 4f4941975d8..00000000000 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed +++ /dev/null @@ -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; -} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed new file mode 100644 index 00000000000..c01784d5076 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed @@ -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; +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr index 6c384a51fac..5e98b77be40 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr @@ -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`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs index b29bff7603f..fe40dabb553 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs @@ -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; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr new file mode 100644 index 00000000000..72c6c05e184 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr @@ -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`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed deleted file mode 100644 index 4f4941975d8..00000000000 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed +++ /dev/null @@ -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; -} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed new file mode 100644 index 00000000000..4ee849b38c5 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed @@ -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; +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr index 6c384a51fac..69cb6c438b6 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr @@ -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); | - ^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs index 9372049a2b2..ab3264704ac 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs @@ -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; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs index 077b52d8f27..3114b9d3bf8 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs @@ -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)) { + // 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(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(Some(0)) { - let _: u32 = x; + 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(&mut x)) = &mut Some(&mut Some(0)) { + if let Some(Some(&&x)) = &Some(Some(&0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected integer, found `&_` let _: u32 = x; } + + // 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)) = &mut Some(&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(x)) = &mut Some(&Some(0)) { - let _: &u32 = x; - } - 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; + if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected integer, found `&mut _` + let _: u32 = x; } - if let Some(&Some(&x)) = &Some(&mut Some(0)) { + + // 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; } - if let Some(&Some(&x)) = &Some(&mut Some(0)) { + + // 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(Some(&x))) = &Some(Some(&mut Some(0))) { + if let Some(&Some(x)) = &mut Some(Some(0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected `Option<{integer}>`, found `&_` let _: u32 = x; } - if let Some(&Some(&x)) = Some(&Some(&mut 0)) { + + // 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)) { + 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; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr new file mode 100644 index 00000000000..e9c338de243 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr @@ -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`. |
