Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit bda9808

Browse files
committedJul 2, 2024
Auto merge of #127008 - Jules-Bertholet:tc-ergonomics, r=Nadrieril
Match ergonomics 2024: Implement TC's match ergonomics proposal Under gate `ref_pat_eat_one_layer_2024_structural`. Enabling `ref_pat_eat_one_layer_2024` at the same time allows the union of what the individual gates allow. `@traviscross` r? `@Nadrieril` cc #123076 `@rustbot` label A-edition-2024 A-patterns
2 parents 7d97c59 + e09815f commit bda9808

12 files changed

+458
-80
lines changed
 

‎compiler/rustc_ast/src/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,7 @@ pub enum ByRef {
711711
}
712712

713713
impl ByRef {
714+
#[must_use]
714715
pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
715716
if let ByRef::Yes(old_mutbl) = &mut self {
716717
*old_mutbl = cmp::min(*old_mutbl, mutbl);

‎compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,8 @@ declare_features! (
575575
(unstable, raw_ref_op, "1.41.0", Some(64490)),
576576
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
577577
(incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
578+
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural variant
579+
(incomplete, ref_pat_eat_one_layer_2024_structural, "CURRENT_RUSTC_VERSION", Some(123076)),
578580
/// Allows using the `#[register_tool]` attribute.
579581
(unstable, register_tool, "1.41.0", Some(66079)),
580582
/// Allows the `#[repr(i128)]` attribute for enums.

‎compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
328328
adjust_mode: AdjustMode,
329329
max_ref_mutbl: MutblCap,
330330
) -> (Ty<'tcx>, ByRef, MutblCap) {
331-
if let ByRef::Yes(Mutability::Mut) = def_br {
332-
debug_assert!(max_ref_mutbl == MutblCap::Mut);
331+
#[cfg(debug_assertions)]
332+
if def_br == ByRef::Yes(Mutability::Mut) && max_ref_mutbl != MutblCap::Mut {
333+
span_bug!(pat.span, "Pattern mutability cap violated!");
333334
}
334335
match adjust_mode {
335336
AdjustMode::Pass => (expected, def_br, max_ref_mutbl),
@@ -437,7 +438,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
437438
});
438439
}
439440

440-
if self.tcx.features().ref_pat_eat_one_layer_2024 {
441+
let features = self.tcx.features();
442+
if features.ref_pat_eat_one_layer_2024 || features.ref_pat_eat_one_layer_2024_structural {
441443
def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl());
442444
if def_br == ByRef::Yes(Mutability::Not) {
443445
max_ref_mutbl = MutblCap::Not;
@@ -669,7 +671,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
669671
// Determine the binding mode...
670672
let bm = match user_bind_annot {
671673
BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
672-
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
674+
if pat.span.at_least_rust_2024()
675+
&& (self.tcx.features().ref_pat_eat_one_layer_2024
676+
|| self.tcx.features().ref_pat_eat_one_layer_2024_structural)
677+
{
673678
if !self.tcx.features().mut_ref {
674679
feature_err(
675680
&self.tcx.sess,
@@ -2123,7 +2128,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21232128
mut expected: Ty<'tcx>,
21242129
mut pat_info: PatInfo<'tcx, '_>,
21252130
) -> Ty<'tcx> {
2126-
let no_ref_mut_behind_and = self.tcx.features().ref_pat_eat_one_layer_2024;
2131+
let tcx = self.tcx;
2132+
let features = tcx.features();
2133+
let ref_pat_eat_one_layer_2024 = features.ref_pat_eat_one_layer_2024;
2134+
let ref_pat_eat_one_layer_2024_structural = features.ref_pat_eat_one_layer_2024_structural;
2135+
2136+
let no_ref_mut_behind_and =
2137+
ref_pat_eat_one_layer_2024 || ref_pat_eat_one_layer_2024_structural;
21272138
let new_match_ergonomics = pat.span.at_least_rust_2024() && no_ref_mut_behind_and;
21282139

21292140
let pat_prefix_span =
@@ -2138,32 +2149,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21382149
pat_info.max_ref_mutbl = MutblCap::Mut;
21392150
}
21402151

2152+
expected = self.try_structurally_resolve_type(pat.span, expected);
21412153
if new_match_ergonomics {
21422154
if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
2143-
// ref pattern consumes inherited reference
2144-
2145-
if pat_mutbl > inh_mut {
2146-
// Tried to match inherited `ref` with `&mut`, which is an error
2147-
let err_msg = "cannot match inherited `&` with `&mut` pattern";
2148-
let err = if let Some(span) = pat_prefix_span {
2149-
let mut err = self.dcx().struct_span_err(span, err_msg);
2150-
err.span_suggestion_verbose(
2151-
span,
2152-
"replace this `&mut` pattern with `&`",
2153-
"&",
2154-
Applicability::MachineApplicable,
2155-
);
2156-
err
2155+
if !ref_pat_eat_one_layer_2024 && let ty::Ref(_, _, r_mutbl) = *expected.kind() {
2156+
// Don't attempt to consume inherited reference
2157+
pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(r_mutbl);
2158+
} else {
2159+
// ref pattern attempts to consume inherited reference
2160+
if pat_mutbl > inh_mut {
2161+
// Tried to match inherited `ref` with `&mut`
2162+
if !ref_pat_eat_one_layer_2024_structural {
2163+
let err_msg = "mismatched types";
2164+
let err = if let Some(span) = pat_prefix_span {
2165+
let mut err = self.dcx().struct_span_err(span, err_msg);
2166+
err.code(E0308);
2167+
err.note("cannot match inherited `&` with `&mut` pattern");
2168+
err.span_suggestion_verbose(
2169+
span,
2170+
"replace this `&mut` pattern with `&`",
2171+
"&",
2172+
Applicability::MachineApplicable,
2173+
);
2174+
err
2175+
} else {
2176+
self.dcx().struct_span_err(pat.span, err_msg)
2177+
};
2178+
err.emit();
2179+
2180+
pat_info.binding_mode = ByRef::No;
2181+
self.typeck_results
2182+
.borrow_mut()
2183+
.skipped_ref_pats_mut()
2184+
.insert(pat.hir_id);
2185+
self.check_pat(inner, expected, pat_info);
2186+
return expected;
2187+
}
21572188
} else {
2158-
self.dcx().struct_span_err(pat.span, err_msg)
2159-
};
2160-
err.emit();
2189+
pat_info.binding_mode = ByRef::No;
2190+
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
2191+
self.check_pat(inner, expected, pat_info);
2192+
return expected;
2193+
}
21612194
}
2162-
2163-
pat_info.binding_mode = ByRef::No;
2164-
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
2165-
self.check_pat(inner, expected, pat_info);
2166-
return expected;
21672195
}
21682196
} else {
21692197
// Reset binding mode on old editions
@@ -2178,8 +2206,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21782206
}
21792207
}
21802208

2181-
let tcx = self.tcx;
2182-
expected = self.try_structurally_resolve_type(pat.span, expected);
21832209
let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) {
21842210
Ok(()) => {
21852211
// `demand::subtype` would be good enough, but using `eqtype` turns

‎compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,7 @@ symbols! {
15131513
recursion_limit,
15141514
reexport_test_harness_main,
15151515
ref_pat_eat_one_layer_2024,
1516+
ref_pat_eat_one_layer_2024_structural,
15161517
ref_pat_everywhere,
15171518
ref_unwind_safe_trait,
15181519
reference,

‎src/tools/tidy/src/features.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ pub fn check(
112112
let file = entry.path();
113113
let filename = file.file_name().unwrap().to_string_lossy();
114114
let filen_underscore = filename.replace('-', "_").replace(".rs", "");
115-
let filename_is_gate_test = test_filen_gate(&filen_underscore, &mut features);
115+
let filename_gate = test_filen_gate(&filen_underscore, &mut features);
116116

117117
for (i, line) in contents.lines().enumerate() {
118118
let mut err = |msg: &str| {
@@ -128,7 +128,7 @@ pub fn check(
128128
};
129129
match features.get_mut(feature_name) {
130130
Some(f) => {
131-
if filename_is_gate_test {
131+
if filename_gate == Some(feature_name) {
132132
err(&format!(
133133
"The file is already marked as gate test \
134134
through its name, no need for a \
@@ -259,18 +259,18 @@ fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> {
259259
r.captures(line).and_then(|c| c.get(1)).map(|m| m.as_str())
260260
}
261261

262-
fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool {
262+
fn test_filen_gate<'f>(filen_underscore: &'f str, features: &mut Features) -> Option<&'f str> {
263263
let prefix = "feature_gate_";
264-
if filen_underscore.starts_with(prefix) {
264+
if let Some(suffix) = filen_underscore.strip_prefix(prefix) {
265265
for (n, f) in features.iter_mut() {
266266
// Equivalent to filen_underscore == format!("feature_gate_{n}")
267-
if &filen_underscore[prefix.len()..] == n {
267+
if suffix == n {
268268
f.has_gate_test = true;
269-
return true;
269+
return Some(suffix);
270270
}
271271
}
272272
}
273-
false
273+
None
274274
}
275275

276276
pub fn collect_lang_features(base_compiler_path: &Path, bad: &mut bool) -> Features {

‎tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//@ edition: 2024
22
//@ compile-flags: -Zunstable-options
3+
// gate-test-ref_pat_eat_one_layer_2024_structural
34

45
pub fn main() {
56
if let Some(Some(&x)) = &Some(&Some(0)) {

‎tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0308]: mismatched types
2-
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:5:22
2+
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:6:22
33
|
44
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
55
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -14,7 +14,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) {
1414
| ~
1515

1616
error[E0308]: mismatched types
17-
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:10:23
17+
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:11:23
1818
|
1919
LL | let _: &u32 = x;
2020
| ---- ^ expected `&u32`, found integer
@@ -27,7 +27,7 @@ LL | let _: &u32 = &x;
2727
| +
2828

2929
error[E0308]: mismatched types
30-
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:13:23
30+
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:14:23
3131
|
3232
LL | if let Some(Some(&&x)) = &Some(Some(&0)) {
3333
| ^^ --------------- this expression has type `&Option<Option<&{integer}>>`
@@ -43,7 +43,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&0)) {
4343
|
4444

4545
error[E0308]: mismatched types
46-
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:17:17
46+
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:18:17
4747
|
4848
LL | if let Some(&Some(x)) = &Some(Some(0)) {
4949
| ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
@@ -54,7 +54,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) {
5454
found reference `&_`
5555

5656
error[E0308]: mismatched types
57-
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22
57+
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:22:22
5858
|
5959
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
6060
| ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
@@ -64,7 +64,7 @@ LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
6464
= note: expected type `{integer}`
6565
found mutable reference `&mut _`
6666
note: to declare a mutable binding use: `mut x`
67-
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22
67+
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:22:22
6868
|
6969
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
7070
| ^^^^^^
@@ -74,7 +74,7 @@ LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) {
7474
| ~
7575

7676
error[E0308]: mismatched types
77-
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:25:22
77+
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:26:22
7878
|
7979
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
8080
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -89,7 +89,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) {
8989
| ~
9090

9191
error[E0308]: mismatched types
92-
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:29:27
92+
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:30:27
9393
|
9494
LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
9595
| ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>`
@@ -104,7 +104,7 @@ LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) {
104104
| ~
105105

106106
error[E0308]: mismatched types
107-
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23
107+
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:34:23
108108
|
109109
LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
110110
| ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>`
@@ -114,7 +114,7 @@ LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
114114
= note: expected type `{integer}`
115115
found mutable reference `&mut _`
116116
note: to declare a mutable binding use: `mut x`
117-
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23
117+
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:34:23
118118
|
119119
LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
120120
| ^^^^^^

‎tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
//@ run-pass
22
//@ edition: 2024
33
//@ compile-flags: -Zunstable-options
4+
//@ revisions: classic structural both
45
#![allow(incomplete_features)]
5-
#![feature(ref_pat_eat_one_layer_2024)]
6+
#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))]
7+
#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))]
68

79
pub fn main() {
810
if let Some(Some(&x)) = &Some(&Some(0)) {
@@ -53,4 +55,12 @@ pub fn main() {
5355
if let Some(&Some(x)) = &mut Some(Some(0)) {
5456
let _: u32 = x;
5557
}
58+
#[cfg(any(classic, both))]
59+
if let Some(&mut x) = &mut Some(&0) {
60+
let _: &u32 = x;
61+
}
62+
#[cfg(any(structural, both))]
63+
if let Some(&mut x) = &Some(&mut 0) {
64+
let _: &u32 = x;
65+
}
5666
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17
3+
|
4+
LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) {
5+
| ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>`
6+
| |
7+
| types differ in mutability
8+
|
9+
= note: expected reference `&Option<{integer}>`
10+
found mutable reference `&mut _`
11+
12+
error[E0308]: mismatched types
13+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23
14+
|
15+
LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
16+
| ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>`
17+
| |
18+
| expected integer, found `&mut _`
19+
|
20+
= note: expected type `{integer}`
21+
found mutable reference `&mut _`
22+
23+
error[E0308]: mismatched types
24+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27
25+
|
26+
LL | let _: &mut u32 = x;
27+
| -------- ^ types differ in mutability
28+
| |
29+
| expected due to this
30+
|
31+
= note: expected mutable reference `&mut u32`
32+
found reference `&{integer}`
33+
34+
error[E0308]: mismatched types
35+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23
36+
|
37+
LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
38+
| ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>`
39+
| |
40+
| expected integer, found `&mut _`
41+
|
42+
= note: expected type `{integer}`
43+
found mutable reference `&mut _`
44+
45+
error[E0308]: mismatched types
46+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29
47+
|
48+
LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
49+
| ^^^^^^ ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
50+
| |
51+
| expected integer, found `&mut _`
52+
|
53+
= note: expected type `{integer}`
54+
found mutable reference `&mut _`
55+
56+
error[E0308]: mismatched types
57+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25: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:28: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:32:9
80+
|
81+
LL | let &mut _ = &&0;
82+
| ^^^^^^ --- this expression has type `&&{integer}`
83+
| |
84+
| types differ in mutability
85+
|
86+
= note: expected reference `&&{integer}`
87+
found mutable reference `&mut _`
88+
89+
error[E0308]: mismatched types
90+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9
91+
|
92+
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
93+
| ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
94+
| |
95+
| types differ in mutability
96+
|
97+
= note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
98+
found mutable reference `&mut _`
99+
100+
error[E0308]: mismatched types
101+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9
102+
|
103+
LL | let &mut _ = &&mut 0;
104+
| ^^^^^^ ------- this expression has type `&&mut {integer}`
105+
| |
106+
| types differ in mutability
107+
|
108+
= note: expected reference `&&mut {integer}`
109+
found mutable reference `&mut _`
110+
111+
error[E0308]: mismatched types
112+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9
113+
|
114+
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
115+
| ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
116+
| |
117+
| types differ in mutability
118+
|
119+
= note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
120+
found mutable reference `&mut _`
121+
122+
error[E0308]: mismatched types
123+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14
124+
|
125+
LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
126+
| ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
127+
| |
128+
| types differ in mutability
129+
|
130+
= note: expected reference `&&&&mut &&&mut &mut {integer}`
131+
found mutable reference `&mut _`
132+
133+
error[E0658]: binding cannot be both mutable and by-reference
134+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13
135+
|
136+
LL | let Foo(mut a) = &Foo(0);
137+
| ^^^^
138+
|
139+
= note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
140+
= help: add `#![feature(mut_ref)]` to the crate attributes to enable
141+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
142+
143+
error[E0658]: binding cannot be both mutable and by-reference
144+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13
145+
|
146+
LL | let Foo(mut a) = &mut Foo(0);
147+
| ^^^^
148+
|
149+
= note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
150+
= help: add `#![feature(mut_ref)]` to the crate attributes to enable
151+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
152+
153+
error: aborting due to 14 previous errors
154+
155+
Some errors have detailed explanations: E0308, E0658.
156+
For more information about an error, try `rustc --explain E0308`.

‎tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr renamed to ‎tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
1-
error: cannot match inherited `&` with `&mut` pattern
2-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:7:17
1+
error[E0308]: mismatched types
2+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17
33
|
44
LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) {
55
| ^^^^^
66
|
7+
= note: cannot match inherited `&` with `&mut` pattern
78
help: replace this `&mut` pattern with `&`
89
|
910
LL | if let Some(&Some(&_)) = &Some(&Some(0)) {
1011
| ~
1112

12-
error: cannot match inherited `&` with `&mut` pattern
13-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:10:23
13+
error[E0308]: mismatched types
14+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23
1415
|
1516
LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
1617
| ^^^^^
1718
|
19+
= note: cannot match inherited `&` with `&mut` pattern
1820
help: replace this `&mut` pattern with `&`
1921
|
2022
LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) {
2123
| ~
2224

2325
error[E0308]: mismatched types
24-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:14:27
26+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27
2527
|
2628
LL | let _: &mut u32 = x;
2729
| -------- ^ types differ in mutability
@@ -31,52 +33,56 @@ LL | let _: &mut u32 = x;
3133
= note: expected mutable reference `&mut u32`
3234
found reference `&{integer}`
3335

34-
error: cannot match inherited `&` with `&mut` pattern
35-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23
36+
error[E0308]: mismatched types
37+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23
3638
|
3739
LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
3840
| ^^^^^
3941
|
42+
= note: cannot match inherited `&` with `&mut` pattern
4043
help: replace this `&mut` pattern with `&`
4144
|
4245
LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) {
4346
| ~
4447

45-
error: cannot match inherited `&` with `&mut` pattern
46-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:29
48+
error[E0308]: mismatched types
49+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29
4750
|
4851
LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
4952
| ^^^^^
5053
|
54+
= note: cannot match inherited `&` with `&mut` pattern
5155
help: replace this `&mut` pattern with `&`
5256
|
5357
LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) {
5458
| ~
5559

56-
error: cannot match inherited `&` with `&mut` pattern
57-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:17
60+
error[E0308]: mismatched types
61+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17
5862
|
5963
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
6064
| ^^^^^
6165
|
66+
= note: cannot match inherited `&` with `&mut` pattern
6267
help: replace this `&mut` pattern with `&`
6368
|
6469
LL | if let Some(&Some(x)) = &Some(Some(0)) {
6570
| ~
6671

67-
error: cannot match inherited `&` with `&mut` pattern
68-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17
72+
error[E0308]: mismatched types
73+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17
6974
|
7075
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
7176
| ^^^^^
7277
|
78+
= note: cannot match inherited `&` with `&mut` pattern
7379
help: replace this `&mut` pattern with `&`
7480
|
7581
LL | if let Some(&Some(x)) = &Some(Some(0)) {
7682
| ~
7783

7884
error[E0308]: mismatched types
79-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9
85+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9
8086
|
8187
LL | let &mut _ = &&0;
8288
| ^^^^^^ --- this expression has type `&&{integer}`
@@ -87,7 +93,7 @@ LL | let &mut _ = &&0;
8793
found mutable reference `&mut _`
8894

8995
error[E0308]: mismatched types
90-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:33:9
96+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9
9197
|
9298
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
9399
| ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
@@ -97,30 +103,32 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
97103
= note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
98104
found mutable reference `&mut _`
99105

100-
error: cannot match inherited `&` with `&mut` pattern
101-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:17
106+
error[E0308]: mismatched types
107+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:38:17
102108
|
103109
LL | if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
104110
| ^^^^^
105111
|
112+
= note: cannot match inherited `&` with `&mut` pattern
106113
help: replace this `&mut` pattern with `&`
107114
|
108115
LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) {
109116
| ~
110117

111-
error: cannot match inherited `&` with `&mut` pattern
112-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:40:22
118+
error[E0308]: mismatched types
119+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:42:22
113120
|
114121
LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
115122
| ^^^^^
116123
|
124+
= note: cannot match inherited `&` with `&mut` pattern
117125
help: replace this `&mut` pattern with `&`
118126
|
119127
LL | if let Some(Some(&x)) = &Some(Some(&mut 0)) {
120128
| ~
121129

122130
error[E0308]: mismatched types
123-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:44:9
131+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9
124132
|
125133
LL | let &mut _ = &&mut 0;
126134
| ^^^^^^ ------- this expression has type `&&mut {integer}`
@@ -131,7 +139,7 @@ LL | let &mut _ = &&mut 0;
131139
found mutable reference `&mut _`
132140

133141
error[E0308]: mismatched types
134-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:47:9
142+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9
135143
|
136144
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
137145
| ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
@@ -142,7 +150,7 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
142150
found mutable reference `&mut _`
143151

144152
error[E0308]: mismatched types
145-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:50:14
153+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14
146154
|
147155
LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
148156
| ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
@@ -153,7 +161,7 @@ LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
153161
found mutable reference `&mut _`
154162

155163
error[E0658]: binding cannot be both mutable and by-reference
156-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:13
164+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13
157165
|
158166
LL | let Foo(mut a) = &Foo(0);
159167
| ^^^^
@@ -163,7 +171,7 @@ LL | let Foo(mut a) = &Foo(0);
163171
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
164172

165173
error[E0658]: binding cannot be both mutable and by-reference
166-
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:59:13
174+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13
167175
|
168176
LL | let Foo(mut a) = &mut Foo(0);
169177
| ^^^^

‎tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,32 @@
11
//@ edition: 2024
22
//@ compile-flags: -Zunstable-options
3+
//@ revisions: classic structural both
34
#![allow(incomplete_features)]
4-
#![feature(ref_pat_eat_one_layer_2024)]
5+
#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))]
6+
#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))]
57

68
pub fn main() {
79
if let Some(&mut Some(&_)) = &Some(&Some(0)) {
8-
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
10+
//~^ ERROR: mismatched types
911
}
1012
if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
11-
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
13+
//~^ ERROR: mismatched types
1214
}
1315
if let Some(&Some(x)) = &mut Some(&Some(0)) {
1416
let _: &mut u32 = x;
1517
//~^ ERROR: mismatched types
1618
}
1719
if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
18-
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
20+
//~^ ERROR: mismatched types
1921
}
2022
if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
21-
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
23+
//~^ ERROR: mismatched types
2224
}
2325
if let Some(&mut Some(x)) = &Some(Some(0)) {
24-
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
26+
//~^ ERROR: mismatched types
2527
}
2628
if let Some(&mut Some(x)) = &Some(Some(0)) {
27-
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
29+
//~^ ERROR: mismatched types
2830
}
2931

3032
let &mut _ = &&0;
@@ -34,11 +36,11 @@ pub fn main() {
3436
//~^ ERROR: mismatched types
3537

3638
if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
37-
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
39+
//[classic]~^ ERROR: mismatched types
3840
}
3941

4042
if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
41-
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
43+
//[classic]~^ ERROR: mismatched types
4244
}
4345

4446
let &mut _ = &&mut 0;
@@ -50,6 +52,10 @@ pub fn main() {
5052
let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
5153
//~^ ERROR: mismatched types
5254

55+
if let Some(&mut _) = &mut Some(&0) {
56+
//[structural]~^ ERROR
57+
}
58+
5359
struct Foo(u8);
5460

5561
let Foo(mut a) = &Foo(0);
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17
3+
|
4+
LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) {
5+
| ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>`
6+
| |
7+
| types differ in mutability
8+
|
9+
= note: expected reference `&Option<{integer}>`
10+
found mutable reference `&mut _`
11+
12+
error[E0308]: mismatched types
13+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23
14+
|
15+
LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
16+
| ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>`
17+
| |
18+
| expected integer, found `&mut _`
19+
|
20+
= note: expected type `{integer}`
21+
found mutable reference `&mut _`
22+
23+
error[E0308]: mismatched types
24+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27
25+
|
26+
LL | let _: &mut u32 = x;
27+
| -------- ^ types differ in mutability
28+
| |
29+
| expected due to this
30+
|
31+
= note: expected mutable reference `&mut u32`
32+
found reference `&{integer}`
33+
34+
error[E0308]: mismatched types
35+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23
36+
|
37+
LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
38+
| ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>`
39+
| |
40+
| expected integer, found `&mut _`
41+
|
42+
= note: expected type `{integer}`
43+
found mutable reference `&mut _`
44+
45+
error[E0308]: mismatched types
46+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29
47+
|
48+
LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
49+
| ^^^^^^ ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
50+
| |
51+
| expected integer, found `&mut _`
52+
|
53+
= note: expected type `{integer}`
54+
found mutable reference `&mut _`
55+
56+
error[E0308]: mismatched types
57+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25: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:28: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:32:9
80+
|
81+
LL | let &mut _ = &&0;
82+
| ^^^^^^ --- this expression has type `&&{integer}`
83+
| |
84+
| types differ in mutability
85+
|
86+
= note: expected reference `&&{integer}`
87+
found mutable reference `&mut _`
88+
89+
error[E0308]: mismatched types
90+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9
91+
|
92+
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
93+
| ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
94+
| |
95+
| types differ in mutability
96+
|
97+
= note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
98+
found mutable reference `&mut _`
99+
100+
error[E0308]: mismatched types
101+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9
102+
|
103+
LL | let &mut _ = &&mut 0;
104+
| ^^^^^^ ------- this expression has type `&&mut {integer}`
105+
| |
106+
| types differ in mutability
107+
|
108+
= note: expected reference `&&mut {integer}`
109+
found mutable reference `&mut _`
110+
111+
error[E0308]: mismatched types
112+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9
113+
|
114+
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
115+
| ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
116+
| |
117+
| types differ in mutability
118+
|
119+
= note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
120+
found mutable reference `&mut _`
121+
122+
error[E0308]: mismatched types
123+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14
124+
|
125+
LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
126+
| ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
127+
| |
128+
| types differ in mutability
129+
|
130+
= note: expected reference `&&&&mut &&&mut &mut {integer}`
131+
found mutable reference `&mut _`
132+
133+
error[E0308]: mismatched types
134+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:17
135+
|
136+
LL | if let Some(&mut _) = &mut Some(&0) {
137+
| ^^^^^^ ------------- this expression has type `&mut Option<&{integer}>`
138+
| |
139+
| types differ in mutability
140+
|
141+
= note: expected reference `&{integer}`
142+
found mutable reference `&mut _`
143+
144+
error[E0658]: binding cannot be both mutable and by-reference
145+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13
146+
|
147+
LL | let Foo(mut a) = &Foo(0);
148+
| ^^^^
149+
|
150+
= note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
151+
= help: add `#![feature(mut_ref)]` to the crate attributes to enable
152+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
153+
154+
error[E0658]: binding cannot be both mutable and by-reference
155+
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13
156+
|
157+
LL | let Foo(mut a) = &mut Foo(0);
158+
| ^^^^
159+
|
160+
= note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
161+
= help: add `#![feature(mut_ref)]` to the crate attributes to enable
162+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
163+
164+
error: aborting due to 15 previous errors
165+
166+
Some errors have detailed explanations: E0308, E0658.
167+
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)
Please sign in to comment.