remove Rule 3 from ref_pat_eat_one_layer_2024

The debug assertion ensuring that the pattern mutability cap holds
assumes the presence of Rule 3, so it now checks for that. I
considered going back to only tracking the mutability cap when Rule 3
is present, but since the mutability cap is used in Rule 5's
implementation too, the debug assertion would still need to check
which typing rules are present.

This also required some changes to tests:
- `ref_pat_eat_one_layer_2021.rs` had a test for Rule 3; I'll be
handling tests for earlier editions in a later commit, so as a stopgap
I've #[cfg]ed it out.
- One test case had to be moved from `well-typed-edition-2024.rs` to
`borrowck-errors.rs` in order to get borrowck to run on it and emit an
error.
This commit is contained in:
dianne 2025-01-02 21:47:54 -08:00
parent f3d1d47fd8
commit a56f9ad574
7 changed files with 22 additions and 34 deletions

View File

@ -243,8 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn downgrade_mut_inside_shared(&self) -> bool {
// NB: RFC 3627 proposes stabilizing Rule 3 in all editions. If we adopt the same behavior
// across all editions, this may be removed.
self.tcx.features().ref_pat_eat_one_layer_2024()
|| self.tcx.features().ref_pat_eat_one_layer_2024_structural()
self.tcx.features().ref_pat_eat_one_layer_2024_structural()
}
/// Experimental pattern feature: when do reference patterns match against inherited references?
@ -425,7 +424,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
max_ref_mutbl: MutblCap,
) -> (Ty<'tcx>, ByRef, MutblCap) {
#[cfg(debug_assertions)]
if def_br == ByRef::Yes(Mutability::Mut) && max_ref_mutbl != MutblCap::Mut {
if def_br == ByRef::Yes(Mutability::Mut)
&& max_ref_mutbl != MutblCap::Mut
&& self.downgrade_mut_inside_shared()
{
span_bug!(pat.span, "Pattern mutability cap violated!");
}
match adjust_mode {

View File

@ -19,7 +19,13 @@ error[E0596]: cannot borrow data in a `&` reference as mutable
LL | let &ref mut x = &0;
| ^^^^^^^^^ cannot borrow as mutable
error: aborting due to 2 previous errors
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/borrowck-errors.rs:17:23
|
LL | if let &Some(Some(x)) = &Some(&mut Some(0)) {
| ^ cannot borrow as mutable
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0507, E0596.
For more information about an error, try `rustc --explain E0507`.

View File

@ -13,4 +13,9 @@ pub fn main() {
let &ref mut x = &0;
//~^ cannot borrow data in a `&` reference as mutable [E0596]
if let &Some(Some(x)) = &Some(&mut Some(0)) {
//[classic]~^ ERROR: cannot borrow data in a `&` reference as mutable
let _: &u32 = x;
}
}

View File

@ -46,18 +46,6 @@ help: replace this `&mut` pattern with `&`
LL | if let Some(&Some(&_)) = &Some(&Some(0)) {
| ~
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:31:23
|
LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
| ^^^^^
|
= note: cannot match inherited `&` with `&mut` pattern
help: replace this `&mut` pattern with `&`
|
LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) {
| ~
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:34:23
|
@ -70,18 +58,6 @@ help: replace this `&mut` pattern with `&`
LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) {
| ~
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:37:29
|
LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
| ^^^^^
|
= note: cannot match inherited `&` with `&mut` pattern
help: replace this `&mut` pattern with `&`
|
LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) {
| ~
error[E0308]: mismatched types
--> $DIR/pattern-errors.rs:40:17
|
@ -106,6 +82,6 @@ help: replace this `&mut` pattern with `&`
LL | if let Some(&Some(x)) = &Some(Some(0)) {
| ~
error: aborting due to 9 previous errors
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -29,13 +29,13 @@ pub fn main() {
//~^ ERROR: mismatched types
}
if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
//~^ ERROR: mismatched types
//[structural]~^ 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
//[structural]~^ ERROR: mismatched types
}
if let Some(&mut Some(x)) = &Some(Some(0)) {
//~^ ERROR: mismatched types

View File

@ -6,9 +6,11 @@
#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
pub fn main() {
#[cfg(structural)]
if let &Some(Some(x)) = &Some(&mut Some(0)) {
let _: &u32 = x;
}
if let Some(&x) = Some(&mut 0) {
let _: u32 = x;
}

View File

@ -35,9 +35,6 @@ pub fn main() {
if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) {
let _: &u32 = x;
}
if let &Some(Some(x)) = &Some(&mut Some(0)) {
let _: &u32 = x;
}
if let Some(&Some(&x)) = &Some(&mut Some(0)) {
let _: u32 = x;
}