Match ergonomics 2024: mut
doesn't reset binding mode
This commit is contained in:
parent
63f70b3d10
commit
ef1d084c0b
8 changed files with 121 additions and 4 deletions
|
@ -533,6 +533,8 @@ declare_features! (
|
||||||
(unstable, more_qualified_paths, "1.54.0", Some(86935)),
|
(unstable, more_qualified_paths, "1.54.0", Some(86935)),
|
||||||
/// Allows the `#[must_not_suspend]` attribute.
|
/// Allows the `#[must_not_suspend]` attribute.
|
||||||
(unstable, must_not_suspend, "1.57.0", Some(83310)),
|
(unstable, must_not_suspend, "1.57.0", Some(83310)),
|
||||||
|
/// Make `mut` not reset the binding mode on edition >= 2024.
|
||||||
|
(unstable, mut_dont_reset_binding_mode_2024, "CURRENT_RUSTC_VERSION", Some(123076)),
|
||||||
/// Allows `mut ref` and `mut ref mut` identifier patterns.
|
/// Allows `mut ref` and `mut ref mut` identifier patterns.
|
||||||
(incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)),
|
(incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)),
|
||||||
/// Allows using `#[naked]` on functions.
|
/// Allows using `#[naked]` on functions.
|
||||||
|
|
|
@ -629,12 +629,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
pat_info: PatInfo<'tcx, '_>,
|
pat_info: PatInfo<'tcx, '_>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let PatInfo { binding_mode: def_bm, top_info: ti, .. } = pat_info;
|
let PatInfo { binding_mode: BindingAnnotation(def_br, _), top_info: ti, .. } = pat_info;
|
||||||
|
|
||||||
// Determine the binding mode...
|
// Determine the binding mode...
|
||||||
let bm = match ba {
|
let bm = match ba {
|
||||||
BindingAnnotation(ByRef::No, Mutability::Not) => def_bm,
|
BindingAnnotation(ByRef::No, Mutability::Mut)
|
||||||
_ => ba,
|
if !(pat.span.at_least_rust_2024()
|
||||||
|
&& self.tcx.features().mut_dont_reset_binding_mode_2024)
|
||||||
|
&& matches!(def_br, ByRef::Yes(_)) =>
|
||||||
|
{
|
||||||
|
// `mut x` resets the binding mode in edition <= 2021.
|
||||||
|
BindingAnnotation(ByRef::No, Mutability::Mut)
|
||||||
|
}
|
||||||
|
BindingAnnotation(ByRef::No, mutbl) => BindingAnnotation(def_br, mutbl),
|
||||||
|
BindingAnnotation(ByRef::Yes(_), _) => ba,
|
||||||
};
|
};
|
||||||
// ...and store it in a side table:
|
// ...and store it in a side table:
|
||||||
self.typeck_results.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm);
|
self.typeck_results.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm);
|
||||||
|
@ -743,7 +751,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Precondition: pat is a Ref(_) pattern
|
/// Precondition: pat is a `Ref(_)` pattern
|
||||||
fn borrow_pat_suggestion(&self, err: &mut Diag<'_>, pat: &Pat<'_>) {
|
fn borrow_pat_suggestion(&self, err: &mut Diag<'_>, pat: &Pat<'_>) {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
if let PatKind::Ref(inner, mutbl) = pat.kind
|
if let PatKind::Ref(inner, mutbl) = pat.kind
|
||||||
|
|
|
@ -1194,6 +1194,7 @@ symbols! {
|
||||||
multiple_supertrait_upcastable,
|
multiple_supertrait_upcastable,
|
||||||
must_not_suspend,
|
must_not_suspend,
|
||||||
must_use,
|
must_use,
|
||||||
|
mut_dont_reset_binding_mode_2024,
|
||||||
mut_ref,
|
mut_ref,
|
||||||
naked,
|
naked,
|
||||||
naked_functions,
|
naked_functions,
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
//@ edition: 2024
|
||||||
|
//@ compile-flags: -Zunstable-options
|
||||||
|
|
||||||
|
struct Foo(u8);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let Foo(mut a) = &Foo(0);
|
||||||
|
a = &42;
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
|
||||||
|
let Foo(mut a) = &mut Foo(0);
|
||||||
|
a = &mut 42;
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/feature-gate-mut_dont_reset_binding_mode_2024.rs:8:9
|
||||||
|
|
|
||||||
|
LL | let Foo(mut a) = &Foo(0);
|
||||||
|
| ----- expected due to the type of this binding
|
||||||
|
LL | a = &42;
|
||||||
|
| ^^^ expected `u8`, found `&{integer}`
|
||||||
|
|
|
||||||
|
help: consider removing the borrow
|
||||||
|
|
|
||||||
|
LL - a = &42;
|
||||||
|
LL + a = 42;
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/feature-gate-mut_dont_reset_binding_mode_2024.rs:12:9
|
||||||
|
|
|
||||||
|
LL | let Foo(mut a) = &mut Foo(0);
|
||||||
|
| ----- expected due to the type of this binding
|
||||||
|
LL | a = &mut 42;
|
||||||
|
| ^^^^^^^ expected `u8`, found `&mut {integer}`
|
||||||
|
|
|
||||||
|
help: consider removing the borrow
|
||||||
|
|
|
||||||
|
LL - a = &mut 42;
|
||||||
|
LL + a = 42;
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
15
tests/ui/pattern/mut_dont_reset_binding_mode_2021.rs
Normal file
15
tests/ui/pattern/mut_dont_reset_binding_mode_2021.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
//@ edition: 2021
|
||||||
|
//@ compile-flags: -Zunstable-options
|
||||||
|
#![feature(mut_dont_reset_binding_mode_2024)]
|
||||||
|
|
||||||
|
struct Foo(u8);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let Foo(mut a) = &Foo(0);
|
||||||
|
a = &42;
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
|
||||||
|
let Foo(mut a) = &mut Foo(0);
|
||||||
|
a = &mut 42;
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
}
|
31
tests/ui/pattern/mut_dont_reset_binding_mode_2021.stderr
Normal file
31
tests/ui/pattern/mut_dont_reset_binding_mode_2021.stderr
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/mut_dont_reset_binding_mode_2021.rs:9:9
|
||||||
|
|
|
||||||
|
LL | let Foo(mut a) = &Foo(0);
|
||||||
|
| ----- expected due to the type of this binding
|
||||||
|
LL | a = &42;
|
||||||
|
| ^^^ expected `u8`, found `&{integer}`
|
||||||
|
|
|
||||||
|
help: consider removing the borrow
|
||||||
|
|
|
||||||
|
LL - a = &42;
|
||||||
|
LL + a = 42;
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/mut_dont_reset_binding_mode_2021.rs:13:9
|
||||||
|
|
|
||||||
|
LL | let Foo(mut a) = &mut Foo(0);
|
||||||
|
| ----- expected due to the type of this binding
|
||||||
|
LL | a = &mut 42;
|
||||||
|
| ^^^^^^^ expected `u8`, found `&mut {integer}`
|
||||||
|
|
|
||||||
|
help: consider removing the borrow
|
||||||
|
|
|
||||||
|
LL - a = &mut 42;
|
||||||
|
LL + a = 42;
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
15
tests/ui/pattern/mut_dont_reset_binding_mode_2024.rs
Normal file
15
tests/ui/pattern/mut_dont_reset_binding_mode_2024.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
//@ run-pass
|
||||||
|
//@ edition: 2024
|
||||||
|
//@ compile-flags: -Zunstable-options
|
||||||
|
#![feature(mut_dont_reset_binding_mode_2024)]
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
struct Foo(u8);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let Foo(mut a) = &Foo(0);
|
||||||
|
a = &42;
|
||||||
|
|
||||||
|
let Foo(mut a) = &mut Foo(0);
|
||||||
|
a = &mut 42;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue