Skip to content

Commit 35c5e67

Browse files
committed
Auto merge of rust-lang#124567 - Jules-Bertholet:and-eats-andmut, r=Nadrieril
Match ergonomics 2024: let `&` patterns eat `&mut` r? `@Nadrieril` cc rust-lang#123076 `@rustbot` label A-edition-2024 A-patterns
2 parents 2259028 + 6d5c6f5 commit 35c5e67

13 files changed

+420
-213
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+219-140
Large diffs are not rendered by default.

tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs

+6
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ pub fn main() {
5353
if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) {
5454
let _: u32 = x;
5555
}
56+
if let Some(&Some(&x)) = Some(&Some(&mut 0)) {
57+
let _: u32 = x;
58+
}
59+
if let Some(&Some(x)) = &mut Some(Some(0)) {
60+
let _: u32 = x;
61+
}
5662

5763
let &mut x = &&mut 0;
5864
let _: &u32 = x;

tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,20 @@ pub fn main() {
1414
let _: &mut u32 = x;
1515
//~^ ERROR: mismatched types
1616
}
17-
if let Some(&Some(&_)) = Some(&Some(&mut 0)) {
18-
//~^ ERROR: mismatched types
19-
}
2017
if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
2118
//~^ ERROR: mismatched types
2219
}
2320
if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
2421
//~^ ERROR: mismatched types
2522
}
23+
if let Some(&mut Some(x)) = &Some(Some(0)) {
24+
//~^ ERROR: mismatched types
25+
}
26+
if let Some(&mut Some(x)) = &Some(Some(0)) {
27+
//~^ ERROR: mismatched types
28+
}
2629

27-
28-
let &mut _= &&0;
30+
let &mut _ = &&0;
2931
//~^ ERROR: mismatched types
3032

3133
let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;

tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr

+28-17
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,6 @@ LL | let _: &mut u32 = x;
3434
error[E0308]: mismatched types
3535
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23
3636
|
37-
LL | if let Some(&Some(&_)) = Some(&Some(&mut 0)) {
38-
| ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>`
39-
| |
40-
| types differ in mutability
41-
|
42-
= note: expected mutable reference `&mut {integer}`
43-
found reference `&_`
44-
45-
error[E0308]: mismatched types
46-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:23
47-
|
4837
LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
4938
| ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>`
5039
| |
@@ -54,7 +43,7 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
5443
found mutable reference `&mut _`
5544

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

6756
error[E0308]: mismatched types
68-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:9
57+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:17
58+
|
59+
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
60+
| ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
61+
| |
62+
| expected `Option<{integer}>`, found `&mut _`
63+
|
64+
= note: expected enum `Option<{integer}>`
65+
found mutable reference `&mut _`
66+
67+
error[E0308]: mismatched types
68+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17
69+
|
70+
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
71+
| ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
72+
| |
73+
| expected `Option<{integer}>`, found `&mut _`
74+
|
75+
= note: expected enum `Option<{integer}>`
76+
found mutable reference `&mut _`
77+
78+
error[E0308]: mismatched types
79+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9
6980
|
70-
LL | let &mut _= &&0;
71-
| ^^^^^^ --- this expression has type `&&{integer}`
81+
LL | let &mut _ = &&0;
82+
| ^^^^^^ --- this expression has type `&&{integer}`
7283
| |
7384
| expected integer, found `&mut _`
7485
|
7586
= note: expected type `{integer}`
7687
found mutable reference `&mut _`
7788

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

89-
error: aborting due to 8 previous errors
100+
error: aborting due to 9 previous errors
90101

91102
For more information about this error, try `rustc --explain E0308`.

tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs

+3
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@ pub fn main() {
88
//~^ ERROR: cannot move out of a shared reference [E0507]
99
let _: &u32 = x;
1010
}
11+
12+
let &ref mut x = &0;
13+
//~^ cannot borrow data in a `&` reference as mutable [E0596]
1114
}

tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr

+9-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ help: consider borrowing the pattern binding
1212
LL | if let Some(&Some(ref x)) = Some(&Some(&mut 0)) {
1313
| +++
1414

15-
error: aborting due to 1 previous error
15+
error[E0596]: cannot borrow data in a `&` reference as mutable
16+
--> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:12:10
17+
|
18+
LL | let &ref mut x = &0;
19+
| ^^^^^^^^^ cannot borrow as mutable
20+
21+
error: aborting due to 2 previous errors
1622

17-
For more information about this error, try `rustc --explain E0507`.
23+
Some errors have detailed explanations: E0507, E0596.
24+
For more information about an error, try `rustc --explain E0507`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//@ edition: 2024
2+
//@ compile-flags: -Zunstable-options
3+
//@ run-rustfix
4+
#![allow(incomplete_features)]
5+
#![feature(ref_pat_eat_one_layer_2024)]
6+
7+
pub fn main() {
8+
if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) {
9+
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
10+
let _: &mut u8 = x;
11+
}
12+
13+
if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) {
14+
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
15+
let _: &mut u8 = x;
16+
}
17+
18+
macro_rules! pat {
19+
($var:ident) => { ref mut $var };
20+
}
21+
let &mut pat!(x) = &mut 0;
22+
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
23+
let _: &mut u8 = x;
24+
25+
let &mut (ref mut a, ref mut b) = &mut (true, false);
26+
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
27+
//~| ERROR: cannot borrow as mutable inside an `&` pattern
28+
let _: &mut bool = a;
29+
let _: &mut bool = b;
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//@ edition: 2024
2+
//@ compile-flags: -Zunstable-options
3+
//@ run-rustfix
4+
#![allow(incomplete_features)]
5+
#![feature(ref_pat_eat_one_layer_2024)]
6+
7+
pub fn main() {
8+
if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
9+
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
10+
let _: &mut u8 = x;
11+
}
12+
13+
if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
14+
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
15+
let _: &mut u8 = x;
16+
}
17+
18+
macro_rules! pat {
19+
($var:ident) => { ref mut $var };
20+
}
21+
let &pat!(x) = &mut 0;
22+
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
23+
let _: &mut u8 = x;
24+
25+
let &(ref mut a, ref mut b) = &mut (true, false);
26+
//~^ ERROR: cannot borrow as mutable inside an `&` pattern
27+
//~| ERROR: cannot borrow as mutable inside an `&` pattern
28+
let _: &mut bool = a;
29+
let _: &mut bool = b;
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
error[E0596]: cannot borrow as mutable inside an `&` pattern
2+
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:8:31
3+
|
4+
LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
5+
| - ^
6+
| |
7+
| help: replace this `&` with `&mut`: `&mut`
8+
9+
error[E0596]: cannot borrow as mutable inside an `&` pattern
10+
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:13:31
11+
|
12+
LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
13+
| - ^
14+
| |
15+
| help: replace this `&` with `&mut`: `&mut`
16+
17+
error[E0596]: cannot borrow as mutable inside an `&` pattern
18+
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:21:15
19+
|
20+
LL | let &pat!(x) = &mut 0;
21+
| - ^
22+
| |
23+
| help: replace this `&` with `&mut`: `&mut`
24+
25+
error[E0596]: cannot borrow as mutable inside an `&` pattern
26+
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:19
27+
|
28+
LL | let &(ref mut a, ref mut b) = &mut (true, false);
29+
| - ^
30+
| |
31+
| help: replace this `&` with `&mut`: `&mut`
32+
33+
error[E0596]: cannot borrow as mutable inside an `&` pattern
34+
--> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:30
35+
|
36+
LL | let &(ref mut a, ref mut b) = &mut (true, false);
37+
| - ^
38+
| |
39+
| help: replace this `&` with `&mut`: `&mut`
40+
41+
error: aborting due to 5 previous errors
42+
43+
For more information about this error, try `rustc --explain E0596`.

tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs tests/ui/match/ref_pat_everywhere-fail.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@ pub fn main() {
55
//~^ ERROR: mismatched types [E0308]
66
let _: u32 = x;
77
}
8-
if let &Some(x) = &mut Some(0) {
9-
//~^ ERROR: mismatched types [E0308]
10-
let _: u32 = x;
11-
}
12-
if let Some(&x) = &mut Some(0) {
8+
if let Some(&mut x) = Some(&0) {
139
//~^ ERROR: mismatched types [E0308]
1410
let _: u32 = x;
1511
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/ref_pat_everywhere-fail.rs:4:17
3+
|
4+
LL | if let Some(&x) = Some(0) {
5+
| ^^ ------- this expression has type `Option<{integer}>`
6+
| |
7+
| expected integer, found `&_`
8+
|
9+
= note: expected type `{integer}`
10+
found reference `&_`
11+
help: consider removing `&` from the pattern
12+
|
13+
LL | if let Some(x) = Some(0) {
14+
| ~
15+
16+
error[E0308]: mismatched types
17+
--> $DIR/ref_pat_everywhere-fail.rs:8:17
18+
|
19+
LL | if let Some(&mut x) = Some(&0) {
20+
| ^^^^^^ -------- this expression has type `Option<&{integer}>`
21+
| |
22+
| types differ in mutability
23+
|
24+
= note: expected reference `&{integer}`
25+
found mutable reference `&mut _`
26+
note: to declare a mutable binding use: `mut x`
27+
--> $DIR/ref_pat_everywhere-fail.rs:8:17
28+
|
29+
LL | if let Some(&mut x) = Some(&0) {
30+
| ^^^^^^
31+
help: consider removing `&mut` from the pattern
32+
|
33+
LL | if let Some(x) = Some(&0) {
34+
| ~
35+
36+
error: aborting due to 2 previous errors
37+
38+
For more information about this error, try `rustc --explain E0308`.

tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr

-44
This file was deleted.

tests/ui/match/ref_pat_everywhere.rs

+6
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,10 @@ pub fn main() {
1515
if let Some(Some(&x)) = &Some(&mut Some(0)) {
1616
let _: u32 = x;
1717
}
18+
if let &Some(x) = &mut Some(0) {
19+
let _: u32 = x;
20+
}
21+
if let Some(&x) = &mut Some(0) {
22+
let _: u32 = x;
23+
}
1824
}

0 commit comments

Comments
 (0)