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
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
(removed, min_type_alias_impl_trait, "1.56.0", Some(63063),
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),
Some("subsumed by `#![feature(allocator_internals)]`")),
/// 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)),
/// Allows the `#[must_not_suspend]` attribute.
(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.
(incomplete, mut_ref, "1.79.0", Some(123076)),
/// Allows using `#[naked]` on functions.

View File

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