Gate implicit mutable by-reference bindings behind mut ref

This commit is contained in:
Jules Bertholet 2024-05-15 16:55:54 -04:00
parent eb91f3b051
commit 0746577fa2
No known key found for this signature in database
GPG Key ID: 32034DAFC38C1BFC
11 changed files with 61 additions and 65 deletions

View File

@ -128,6 +128,8 @@ declare_features! (
/// Allows the use of type alias impl trait in function return positions /// Allows the use of type alias impl trait in function return positions
(removed, min_type_alias_impl_trait, "1.56.0", Some(63063), (removed, min_type_alias_impl_trait, "1.56.0", Some(63063),
Some("removed in favor of full type_alias_impl_trait")), Some("removed in favor of full type_alias_impl_trait")),
/// Make `mut` not reset the binding mode on edition >= 2024.
(removed, mut_preserve_binding_mode_2024, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024`")),
(removed, needs_allocator, "1.4.0", Some(27389), (removed, needs_allocator, "1.4.0", Some(27389),
Some("subsumed by `#![feature(allocator_internals)]`")), Some("subsumed by `#![feature(allocator_internals)]`")),
/// Allows use of unary negate on unsigned integers, e.g., -e for e: u8 /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8

View File

@ -527,8 +527,6 @@ 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.
(incomplete, mut_preserve_binding_mode_2024, "1.79.0", Some(123076)),
/// Allows `mut ref` and `mut ref mut` identifier patterns. /// Allows `mut ref` and `mut ref mut` identifier patterns.
(incomplete, mut_ref, "1.79.0", Some(123076)), (incomplete, mut_ref, "1.79.0", Some(123076)),
/// Allows using `#[naked]` on functions. /// Allows using `#[naked]` on functions.

View File

@ -12,7 +12,7 @@ use rustc_infer::infer;
use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_session::{lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS, parse::feature_err};
use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::hygiene::DesugaringKind; use rustc_span::hygiene::DesugaringKind;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
@ -669,17 +669,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Determine the binding mode... // Determine the binding mode...
let bm = match user_bind_annot { let bm = match user_bind_annot {
// `mut` resets binding mode on edition <= 2021 BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
BindingMode(ByRef::No, Mutability::Mut) if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
if !(pat.span.at_least_rust_2024() if !self.tcx.features().mut_ref {
&& self.tcx.features().mut_preserve_binding_mode_2024) feature_err(
&& matches!(def_br, ByRef::Yes(_)) => &self.tcx.sess,
{ sym::mut_ref,
self.typeck_results pat.span.until(ident.span),
.borrow_mut() "binding cannot be both mutable and by-reference",
.rust_2024_migration_desugared_pats_mut() )
.insert(pat_info.top_info.hir_id); .emit();
BindingMode(ByRef::No, Mutability::Mut) }
BindingMode(def_br, Mutability::Mut)
} else {
// `mut` resets binding mode on edition <= 2021
self.typeck_results
.borrow_mut()
.rust_2024_migration_desugared_pats_mut()
.insert(pat_info.top_info.hir_id);
BindingMode(ByRef::No, Mutability::Mut)
}
} }
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl), BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
BindingMode(ByRef::Yes(_), _) => user_bind_annot, BindingMode(ByRef::Yes(_), _) => user_bind_annot,

View File

@ -49,4 +49,14 @@ pub fn main() {
let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
//~^ ERROR: mismatched types //~^ ERROR: mismatched types
struct Foo(u8);
let Foo(mut a) = &Foo(0);
//~^ ERROR: binding cannot be both mutable and by-reference
a = &42;
let Foo(mut a) = &mut Foo(0);
//~^ ERROR: binding cannot be both mutable and by-reference
a = &mut 42;
} }

View File

@ -152,6 +152,27 @@ LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
= note: expected reference `&&&&mut &&&mut &mut {integer}` = note: expected reference `&&&&mut &&&mut &mut {integer}`
found mutable reference `&mut _` found mutable reference `&mut _`
error: aborting due to 14 previous errors error[E0658]: binding cannot be both mutable and by-reference
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:13
|
LL | let Foo(mut a) = &Foo(0);
| ^^^^
|
= note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
= help: add `#![feature(mut_ref)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
For more information about this error, try `rustc --explain E0308`. error[E0658]: binding cannot be both mutable and by-reference
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:59:13
|
LL | let Foo(mut a) = &mut Foo(0);
| ^^^^
|
= note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
= help: add `#![feature(mut_ref)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 16 previous errors
Some errors have detailed explanations: E0308, E0658.
For more information about an error, try `rustc --explain E0308`.

View File

@ -1,14 +0,0 @@
//@ 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
}

View File

@ -1,31 +0,0 @@
error[E0308]: mismatched types
--> $DIR/feature-gate-mut_preserve_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_preserve_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`.

View File

@ -2,7 +2,7 @@
//@ run-rustfix //@ run-rustfix
//@ rustfix-only-machine-applicable //@ rustfix-only-machine-applicable
//@ aux-build:match_ergonomics_2024_macros.rs //@ aux-build:match_ergonomics_2024_macros.rs
#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)] #![feature(mut_ref, ref_pat_eat_one_layer_2024)]
#![allow(incomplete_features, unused)] #![allow(incomplete_features, unused)]
#![deny(rust_2024_incompatible_pat)] #![deny(rust_2024_incompatible_pat)]

View File

@ -2,7 +2,7 @@
//@ run-rustfix //@ run-rustfix
//@ rustfix-only-machine-applicable //@ rustfix-only-machine-applicable
//@ aux-build:match_ergonomics_2024_macros.rs //@ aux-build:match_ergonomics_2024_macros.rs
#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)] #![feature(mut_ref, ref_pat_eat_one_layer_2024)]
#![allow(incomplete_features, unused)] #![allow(incomplete_features, unused)]
#![deny(rust_2024_incompatible_pat)] #![deny(rust_2024_incompatible_pat)]

View File

@ -1,6 +1,6 @@
//@ edition: 2021 //@ edition: 2021
//@ compile-flags: -Zunstable-options //@ compile-flags: -Zunstable-options
#![feature(mut_preserve_binding_mode_2024)] #![feature(ref_pat_eat_one_layer_2024)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
struct Foo(u8); struct Foo(u8);

View File

@ -1,7 +1,7 @@
//@ run-pass //@ run-pass
//@ edition: 2024 //@ edition: 2024
//@ compile-flags: -Zunstable-options //@ compile-flags: -Zunstable-options
#![feature(mut_preserve_binding_mode_2024)] #![feature(mut_ref, ref_pat_eat_one_layer_2024)]
#![allow(incomplete_features, unused)] #![allow(incomplete_features, unused)]
struct Foo(u8); struct Foo(u8);