Skip to content

Commit ef22c14

Browse files
Rollup merge of #136397 - Shunpoco:issue-136223-ICE-pattern-mutability-cap-violated, r=Nadrieril
Add a comment pointing to ICE-136223 Fixes #136223 ## Steps how the ICE happen This explanation is based on the test case `&Some(Some(x)) = &Some(&mut Some(0))`. The case should fail with E0596 error, but it catches the debug assertion instead. 1. For the first `&`: In check_pat_ref(), the value max_ref_mutbl becomes MutblCap::Not ([here](https://github.com/rust-lang/rust/blob/fdd1a3b02687817cea41f6bacae3d5fbed2b2cd0/compiler/rustc_hir_typeck/src/pat.rs#L2394-L2396)). Once max_ref_mutbl becomes Not, it will never be back to MutblCap::Mut. 2. For `&mut`: In peel_off_references(), because Some(x) doesn't have `&` nor `&mut`, `&mut` in `&mut Some(0)` is not consumed then default_binding_mode (def_br) becomes `ByRef::Yes(Mutability::Mut)` (around [here](https://github.com/rust-lang/rust/blob/fdd1a3b02687817cea41f6bacae3d5fbed2b2cd0/compiler/rustc_hir_typeck/src/pat.rs#L519-L536)). This will be inherited to the next step. So this pattern has the mismatch between `def_br=Yes(Mut)` and `max_ref_mutbl=Not` now. 3. For the value `0`: Because of the step 2, the default_binding_mode is `Yes(Mut)`, but max_ref_mutbl is `Not` from the step 1. It causes the assertion error [here](https://github.com/rust-lang/rust/blob/fdd1a3b02687817cea41f6bacae3d5fbed2b2cd0/compiler/rustc_hir_typeck/src/pat.rs#L427-L430). ## What this PR fixes Step 1 has happened from [this commit](e2f3ce9) by deleting `no_ref_mut_behind_and` from the if block. In my understanding, after RFC3627 is released, step 1 should happen not only 2024 edition but also other editions to track MutblCap value. But for now, it should not happen for non-2024 edition. So I put it back. NOTE: I think there is another solution - We should return an E0596 error in calc_default_binding_mode() instead of the debug assertion. Since the assertion is caused by the mismatch between `def_br = Yes(Mut)` and `max_ref_mutbl = Not`, but in my understanding this violation is the same as E0596. check_pat_ident() does returns E0596 by a similar reason [here](https://github.com/rust-lang/rust/blob/fdd1a3b02687817cea41f6bacae3d5fbed2b2cd0/compiler/rustc_hir_typeck/src/pat.rs#L837-L856).
2 parents 43ca9d1 + ba12489 commit ef22c14

File tree

3 files changed

+7
-5
lines changed

3 files changed

+7
-5
lines changed

Diff for: tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,19 @@ LL | let &ref mut x = &0;
4848
| ^^^^^^^^^ cannot borrow as mutable
4949

5050
error[E0596]: cannot borrow data in a `&` reference as mutable
51-
--> $DIR/borrowck-errors.rs:35:23
51+
--> $DIR/borrowck-errors.rs:37:23
5252
|
5353
LL | if let &Some(Some(x)) = &Some(&mut Some(0)) {
5454
| ^ cannot borrow as mutable
5555

5656
error[E0596]: cannot borrow data in a `&` reference as mutable
57-
--> $DIR/borrowck-errors.rs:40:11
57+
--> $DIR/borrowck-errors.rs:42:11
5858
|
5959
LL | let &[x] = &&mut [0];
6060
| ^ cannot borrow as mutable
6161

6262
error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array
63-
--> $DIR/borrowck-errors.rs:44:20
63+
--> $DIR/borrowck-errors.rs:46:20
6464
|
6565
LL | let [&mut x] = &mut [&mut 0];
6666
| - ^^^^^^^^^^^^^ cannot move out of here

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

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ pub fn main() {
3232
let &ref mut x = &0;
3333
//~^ cannot borrow data in a `&` reference as mutable [E0596]
3434

35+
// For 2021 edition, this is also a regression test for #136223
36+
// since the maximum mutability is downgraded during the pattern check process.
3537
if let &Some(Some(x)) = &Some(&mut Some(0)) {
3638
//[stable2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable
3739
let _: &u32 = x;

Diff for: tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ LL | let &ref mut x = &0;
5252
| ^^^^^^^^^ cannot borrow as mutable
5353

5454
error[E0596]: cannot borrow data in a `&` reference as mutable
55-
--> $DIR/borrowck-errors.rs:35:23
55+
--> $DIR/borrowck-errors.rs:37:23
5656
|
5757
LL | if let &Some(Some(x)) = &Some(&mut Some(0)) {
5858
| ^ cannot borrow as mutable
5959

6060
error[E0596]: cannot borrow data in a `&` reference as mutable
61-
--> $DIR/borrowck-errors.rs:40:11
61+
--> $DIR/borrowck-errors.rs:42:11
6262
|
6363
LL | let &[x] = &&mut [0];
6464
| ^ cannot borrow as mutable

0 commit comments

Comments
 (0)