Skip to content

Commit

Permalink
Auto merge of #124567 - Jules-Bertholet:and-eats-andmut, r=Nadrieril
Browse files Browse the repository at this point in the history
Match ergonomics 2024: let `&` patterns eat `&mut`

r? `@Nadrieril`

cc #123076

`@rustbot` label A-edition-2024 A-patterns
  • Loading branch information
bors committed May 11, 2024
2 parents 2259028 + 6d5c6f5 commit 35c5e67
Show file tree
Hide file tree
Showing 13 changed files with 420 additions and 213 deletions.
359 changes: 219 additions & 140 deletions compiler/rustc_hir_typeck/src/pat.rs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ pub fn main() {
if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) {
let _: u32 = x;
}
if let Some(&Some(&x)) = Some(&Some(&mut 0)) {
let _: u32 = x;
}
if let Some(&Some(x)) = &mut Some(Some(0)) {
let _: u32 = x;
}

let &mut x = &&mut 0;
let _: &u32 = x;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,20 @@ pub fn main() {
let _: &mut u32 = x;
//~^ ERROR: mismatched types
}
if let Some(&Some(&_)) = Some(&Some(&mut 0)) {
//~^ ERROR: mismatched types
}
if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
//~^ ERROR: mismatched types
}
if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
//~^ ERROR: mismatched types
}
if let Some(&mut Some(x)) = &Some(Some(0)) {
//~^ ERROR: mismatched types
}
if let Some(&mut Some(x)) = &Some(Some(0)) {
//~^ ERROR: mismatched types
}


let &mut _= &&0;
let &mut _ = &&0;
//~^ ERROR: mismatched types

let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,6 @@ LL | let _: &mut u32 = x;
error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23
|
LL | if let Some(&Some(&_)) = Some(&Some(&mut 0)) {
| ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>`
| |
| types differ in mutability
|
= note: expected mutable reference `&mut {integer}`
found reference `&_`

error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:23
|
LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
| ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>`
| |
Expand All @@ -54,7 +43,7 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
found mutable reference `&mut _`

error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:29
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:29
|
LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
| ^^^^^^ ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
Expand All @@ -65,18 +54,40 @@ LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
found mutable reference `&mut _`

error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:9
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:17
|
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
| ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
| |
| expected `Option<{integer}>`, found `&mut _`
|
= note: expected enum `Option<{integer}>`
found mutable reference `&mut _`

error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17
|
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
| ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
| |
| expected `Option<{integer}>`, found `&mut _`
|
= note: expected enum `Option<{integer}>`
found mutable reference `&mut _`

error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9
|
LL | let &mut _= &&0;
| ^^^^^^ --- this expression has type `&&{integer}`
LL | let &mut _ = &&0;
| ^^^^^^ --- this expression has type `&&{integer}`
| |
| expected integer, found `&mut _`
|
= note: expected type `{integer}`
found mutable reference `&mut _`

error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:33:9
|
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
| ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
Expand All @@ -86,6 +97,6 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
= note: expected type `{integer}`
found mutable reference `&mut _`

error: aborting due to 8 previous errors
error: aborting due to 9 previous errors

For more information about this error, try `rustc --explain E0308`.
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ pub fn main() {
//~^ ERROR: cannot move out of a shared reference [E0507]
let _: &u32 = x;
}

let &ref mut x = &0;
//~^ cannot borrow data in a `&` reference as mutable [E0596]
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ help: consider borrowing the pattern binding
LL | if let Some(&Some(ref x)) = Some(&Some(&mut 0)) {
| +++

error: aborting due to 1 previous error
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:12:10
|
LL | let &ref mut x = &0;
| ^^^^^^^^^ cannot borrow as mutable

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0507`.
Some errors have detailed explanations: E0507, E0596.
For more information about an error, try `rustc --explain E0507`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//@ edition: 2024
//@ compile-flags: -Zunstable-options
//@ run-rustfix
#![allow(incomplete_features)]
#![feature(ref_pat_eat_one_layer_2024)]

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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//@ edition: 2024
//@ compile-flags: -Zunstable-options
//@ run-rustfix
#![allow(incomplete_features)]
#![feature(ref_pat_eat_one_layer_2024)]

pub fn main() {
if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
//~^ 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
let _: &mut u8 = x;
}

macro_rules! pat {
($var:ident) => { ref mut $var };
}
let &pat!(x) = &mut 0;
//~^ 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
let _: &mut bool = a;
let _: &mut bool = b;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:8:31
|
LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`

error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:13:31
|
LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`

error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:21:15
|
LL | let &pat!(x) = &mut 0;
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`

error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:19
|
LL | let &(ref mut a, ref mut b) = &mut (true, false);
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`

error[E0596]: cannot borrow as mutable inside an `&` pattern
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:30
|
LL | let &(ref mut a, ref mut b) = &mut (true, false);
| - ^
| |
| help: replace this `&` with `&mut`: `&mut`

error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0596`.
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ pub fn main() {
//~^ ERROR: mismatched types [E0308]
let _: u32 = x;
}
if let &Some(x) = &mut Some(0) {
//~^ ERROR: mismatched types [E0308]
let _: u32 = x;
}
if let Some(&x) = &mut Some(0) {
if let Some(&mut x) = Some(&0) {
//~^ ERROR: mismatched types [E0308]
let _: u32 = x;
}
Expand Down
38 changes: 38 additions & 0 deletions tests/ui/match/ref_pat_everywhere-fail.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
error[E0308]: mismatched types
--> $DIR/ref_pat_everywhere-fail.rs:4:17
|
LL | if let Some(&x) = Some(0) {
| ^^ ------- this expression has type `Option<{integer}>`
| |
| expected integer, found `&_`
|
= note: expected type `{integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL | if let Some(x) = Some(0) {
| ~

error[E0308]: mismatched types
--> $DIR/ref_pat_everywhere-fail.rs:8:17
|
LL | if let Some(&mut x) = Some(&0) {
| ^^^^^^ -------- this expression has type `Option<&{integer}>`
| |
| types differ in mutability
|
= note: expected reference `&{integer}`
found mutable reference `&mut _`
note: to declare a mutable binding use: `mut x`
--> $DIR/ref_pat_everywhere-fail.rs:8:17
|
LL | if let Some(&mut x) = Some(&0) {
| ^^^^^^
help: consider removing `&mut` from the pattern
|
LL | if let Some(x) = Some(&0) {
| ~

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.
44 changes: 0 additions & 44 deletions tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr

This file was deleted.

6 changes: 6 additions & 0 deletions tests/ui/match/ref_pat_everywhere.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,10 @@ pub fn main() {
if let Some(Some(&x)) = &Some(&mut Some(0)) {
let _: u32 = x;
}
if let &Some(x) = &mut Some(0) {
let _: u32 = x;
}
if let Some(&x) = &mut Some(0) {
let _: u32 = x;
}
}

0 comments on commit 35c5e67

Please sign in to comment.