Skip to content

Commit 8738f93

Browse files
committed
"structural" ruleset: account for dbm mutability cap in Deref(EatInner) rules
1 parent 03e9c4d commit 8738f93

File tree

6 files changed

+111
-13
lines changed

6 files changed

+111
-13
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2311,7 +2311,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23112311
InheritedRefMatchRule::EatInner => {
23122312
if let ty::Ref(_, _, r_mutbl) = *expected.kind() {
23132313
// Match against the reference type; don't consume the inherited ref.
2314-
pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(r_mutbl);
2314+
// NB: For RFC 3627's Rule 3, we limit the default binding mode's ref
2315+
// mutability to `pat_info.max_ref_mutbl`. If we implement a pattern typing
2316+
// ruleset with Rule 4 but not Rule 3, we'll need to check that here.
2317+
let mutbl_cap = cmp::min(r_mutbl, pat_info.max_ref_mutbl.as_mutbl());
2318+
pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(mutbl_cap);
23152319
} else {
23162320
// The expected type isn't a reference, so match against the inherited ref.
23172321
if pat_mutbl > inh_mut {

tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ LL | let [&ref x] = &[&mut 0];
4646
| +++
4747

4848
error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array
49-
--> $DIR/borrowck-errors.rs:31:16
49+
--> $DIR/borrowck-errors.rs:30:16
5050
|
5151
LL | let [&x] = &mut [&mut 0];
5252
| - ^^^^^^^^^^^^^ cannot move out of here

tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ pub fn main() {
2727
//[classic]~^ ERROR: cannot move out of type
2828
let _: &u32 = x;
2929

30-
#[cfg(classic)] // TODO: this should pass on `structural` but doesn't
31-
let [&x] = &mut [&mut 0]; //[classic]~ ERROR: cannot move out of type
30+
let [&x] = &mut [&mut 0];
31+
//[classic]~^ ERROR: cannot move out of type
3232
let _: &u32 = x;
3333

3434
let [&mut x] = &mut [&mut 0];

tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) {
8383
| ~
8484

8585
error[E0308]: mismatched types
86-
--> $DIR/pattern-errors.rs:119:10
86+
--> $DIR/pattern-errors.rs:125:10
8787
|
8888
LL | let [&mut x] = &[&mut 0];
8989
| ^^^^^
@@ -95,7 +95,7 @@ LL | let [&x] = &[&mut 0];
9595
| ~
9696

9797
error[E0308]: mismatched types
98-
--> $DIR/pattern-errors.rs:124:10
98+
--> $DIR/pattern-errors.rs:130:10
9999
|
100100
LL | let [&mut &x] = &[&mut 0];
101101
| ^^^^^
@@ -107,7 +107,7 @@ LL | let [&&x] = &[&mut 0];
107107
| ~
108108

109109
error[E0308]: mismatched types
110-
--> $DIR/pattern-errors.rs:129:10
110+
--> $DIR/pattern-errors.rs:135:10
111111
|
112112
LL | let [&mut &ref x] = &[&mut 0];
113113
| ^^^^^
@@ -119,7 +119,7 @@ LL | let [&&ref x] = &[&mut 0];
119119
| ~
120120

121121
error[E0308]: mismatched types
122-
--> $DIR/pattern-errors.rs:134:10
122+
--> $DIR/pattern-errors.rs:140:10
123123
|
124124
LL | let [&mut &(mut x)] = &[&mut 0];
125125
| ^^^^^

tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs

+6
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,16 @@ fn structural_errors_2() {
9696
//[structural]~^ ERROR: mismatched types
9797

9898
let [&&mut x] = &mut [&mut 0];
99+
//[structural]~^ ERROR: mismatched types
99100
let _: u32 = x;
101+
//[structural]~^ ERROR: mismatched types
100102

101103
let [&&mut ref x] = &[&mut 0];
102104
//[structural]~^ ERROR: mismatched types
103105
let _: &u32 = x;
104106

105107
let [&&mut ref x] = &mut [&mut 0];
108+
//[structural]~^ ERROR: mismatched types
106109
let _: &u32 = x;
107110

108111
let [&&mut mut x] = &[&mut 0];
@@ -112,7 +115,10 @@ fn structural_errors_2() {
112115
//[structural]~^ ERROR: mismatched types
113116

114117
let [&&mut mut x] = &mut [&mut 0];
118+
//[structural]~^ ERROR: binding cannot be both mutable and by-reference
119+
//[structural]~| ERROR: mismatched types
115120
let _: u32 = x;
121+
//[structural]~^ ERROR: mismatched types
116122
}
117123

118124
fn classic_errors_0() {

tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr

+93-5
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,38 @@ LL | let _: u32 = *x;
342342
| +
343343

344344
error[E0308]: mismatched types
345-
--> $DIR/pattern-errors.rs:101:11
345+
--> $DIR/pattern-errors.rs:98:11
346+
|
347+
LL | let [&&mut x] = &mut [&mut 0];
348+
| ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]`
349+
| |
350+
| expected integer, found `&mut _`
351+
|
352+
= note: expected type `{integer}`
353+
found mutable reference `&mut _`
354+
help: consider removing `&mut` from the pattern
355+
|
356+
LL - let [&&mut x] = &mut [&mut 0];
357+
LL + let [&x] = &mut [&mut 0];
358+
|
359+
360+
error[E0308]: mismatched types
361+
--> $DIR/pattern-errors.rs:100:18
362+
|
363+
LL | let _: u32 = x;
364+
| --- ^ expected `u32`, found `&_`
365+
| |
366+
| expected due to this
367+
|
368+
= note: expected type `u32`
369+
found reference `&_`
370+
help: consider dereferencing the borrow
371+
|
372+
LL | let _: u32 = *x;
373+
| +
374+
375+
error[E0308]: mismatched types
376+
--> $DIR/pattern-errors.rs:103:11
346377
|
347378
LL | let [&&mut ref x] = &[&mut 0];
348379
| ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]`
@@ -358,7 +389,23 @@ LL + let [&ref x] = &[&mut 0];
358389
|
359390

360391
error[E0308]: mismatched types
361-
--> $DIR/pattern-errors.rs:108:11
392+
--> $DIR/pattern-errors.rs:107:11
393+
|
394+
LL | let [&&mut ref x] = &mut [&mut 0];
395+
| ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]`
396+
| |
397+
| expected integer, found `&mut _`
398+
|
399+
= note: expected type `{integer}`
400+
found mutable reference `&mut _`
401+
help: consider removing `&mut` from the pattern
402+
|
403+
LL - let [&&mut ref x] = &mut [&mut 0];
404+
LL + let [&ref x] = &mut [&mut 0];
405+
|
406+
407+
error[E0308]: mismatched types
408+
--> $DIR/pattern-errors.rs:111:11
362409
|
363410
LL | let [&&mut mut x] = &[&mut 0];
364411
| ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]`
@@ -374,7 +421,7 @@ LL + let [&mut x] = &[&mut 0];
374421
|
375422

376423
error[E0658]: binding cannot be both mutable and by-reference
377-
--> $DIR/pattern-errors.rs:108:16
424+
--> $DIR/pattern-errors.rs:111:16
378425
|
379426
LL | let [&&mut mut x] = &[&mut 0];
380427
| ^^^^
@@ -384,7 +431,48 @@ LL | let [&&mut mut x] = &[&mut 0];
384431
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
385432

386433
error[E0308]: mismatched types
387-
--> $DIR/pattern-errors.rs:111:18
434+
--> $DIR/pattern-errors.rs:114:18
435+
|
436+
LL | let _: u32 = x;
437+
| --- ^ expected `u32`, found `&_`
438+
| |
439+
| expected due to this
440+
|
441+
= note: expected type `u32`
442+
found reference `&_`
443+
help: consider dereferencing the borrow
444+
|
445+
LL | let _: u32 = *x;
446+
| +
447+
448+
error[E0308]: mismatched types
449+
--> $DIR/pattern-errors.rs:117:11
450+
|
451+
LL | let [&&mut mut x] = &mut [&mut 0];
452+
| ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]`
453+
| |
454+
| expected integer, found `&mut _`
455+
|
456+
= note: expected type `{integer}`
457+
found mutable reference `&mut _`
458+
help: consider removing `&mut` from the pattern
459+
|
460+
LL - let [&&mut mut x] = &mut [&mut 0];
461+
LL + let [&mut x] = &mut [&mut 0];
462+
|
463+
464+
error[E0658]: binding cannot be both mutable and by-reference
465+
--> $DIR/pattern-errors.rs:117:16
466+
|
467+
LL | let [&&mut mut x] = &mut [&mut 0];
468+
| ^^^^
469+
|
470+
= note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
471+
= help: add `#![feature(mut_ref)]` to the crate attributes to enable
472+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
473+
474+
error[E0308]: mismatched types
475+
--> $DIR/pattern-errors.rs:120:18
388476
|
389477
LL | let _: u32 = x;
390478
| --- ^ expected `u32`, found `&_`
@@ -398,7 +486,7 @@ help: consider dereferencing the borrow
398486
LL | let _: u32 = *x;
399487
| +
400488

401-
error: aborting due to 27 previous errors
489+
error: aborting due to 33 previous errors
402490

403491
Some errors have detailed explanations: E0308, E0658.
404492
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)