"No ref mut
behind &
" on all editions
This commit is contained in:
parent
0746577fa2
commit
af75014cc5
@ -406,7 +406,7 @@ fn peel_off_references(
|
|||||||
pat: &'tcx Pat<'tcx>,
|
pat: &'tcx Pat<'tcx>,
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
mut def_br: ByRef,
|
mut def_br: ByRef,
|
||||||
mut max_ref_mutability: MutblCap,
|
mut max_ref_mutbl: MutblCap,
|
||||||
) -> (Ty<'tcx>, ByRef, MutblCap) {
|
) -> (Ty<'tcx>, ByRef, MutblCap) {
|
||||||
let mut expected = self.try_structurally_resolve_type(pat.span, expected);
|
let mut expected = self.try_structurally_resolve_type(pat.span, expected);
|
||||||
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
|
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
|
||||||
@ -438,10 +438,10 @@ fn peel_off_references(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
|
if self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||||
def_br = def_br.cap_ref_mutability(max_ref_mutability.as_mutbl());
|
def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl());
|
||||||
if def_br == ByRef::Yes(Mutability::Not) {
|
if def_br == ByRef::Yes(Mutability::Not) {
|
||||||
max_ref_mutability = MutblCap::Not;
|
max_ref_mutbl = MutblCap::Not;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,7 +453,7 @@ fn peel_off_references(
|
|||||||
.insert(pat.hir_id, pat_adjustments);
|
.insert(pat.hir_id, pat_adjustments);
|
||||||
}
|
}
|
||||||
|
|
||||||
(expected, def_br, max_ref_mutability)
|
(expected, def_br, max_ref_mutbl)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_pat_lit(
|
fn check_pat_lit(
|
||||||
@ -2130,18 +2130,22 @@ fn check_pat_ref(
|
|||||||
mut expected: Ty<'tcx>,
|
mut expected: Ty<'tcx>,
|
||||||
mut pat_info: PatInfo<'tcx, '_>,
|
mut pat_info: PatInfo<'tcx, '_>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let new_match_ergonomics =
|
let no_ref_mut_behind_and = self.tcx.features().ref_pat_eat_one_layer_2024;
|
||||||
pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024;
|
let new_match_ergonomics = pat.span.at_least_rust_2024() && no_ref_mut_behind_and;
|
||||||
|
|
||||||
if new_match_ergonomics {
|
let pat_prefix_span =
|
||||||
let pat_prefix_span =
|
inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end));
|
||||||
inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end));
|
|
||||||
|
|
||||||
|
if no_ref_mut_behind_and {
|
||||||
if pat_mutbl == Mutability::Not {
|
if pat_mutbl == Mutability::Not {
|
||||||
// Prevent the inner pattern from binding with `ref mut`.
|
// Prevent the inner pattern from binding with `ref mut`.
|
||||||
pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span);
|
pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
pat_info.max_ref_mutbl = MutblCap::Mut;
|
||||||
|
}
|
||||||
|
|
||||||
|
if new_match_ergonomics {
|
||||||
if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
|
if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
|
||||||
// ref pattern consumes inherited reference
|
// ref pattern consumes inherited reference
|
||||||
|
|
||||||
@ -2179,8 +2183,6 @@ fn check_pat_ref(
|
|||||||
.rust_2024_migration_desugared_pats_mut()
|
.rust_2024_migration_desugared_pats_mut()
|
||||||
.insert(pat_info.top_info.hir_id);
|
.insert(pat_info.top_info.hir_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pat_info.max_ref_mutbl = MutblCap::Mut;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
@ -2195,16 +2197,17 @@ fn check_pat_ref(
|
|||||||
// the bad interactions of the given hack detailed in (note_1).
|
// the bad interactions of the given hack detailed in (note_1).
|
||||||
debug!("check_pat_ref: expected={:?}", expected);
|
debug!("check_pat_ref: expected={:?}", expected);
|
||||||
match *expected.kind() {
|
match *expected.kind() {
|
||||||
ty::Ref(_, r_ty, r_mutbl) if r_mutbl >= pat_mutbl && new_match_ergonomics => {
|
ty::Ref(_, r_ty, r_mutbl)
|
||||||
if r_mutbl == Mutability::Not {
|
if (new_match_ergonomics && r_mutbl >= pat_mutbl)
|
||||||
|
|| r_mutbl == pat_mutbl =>
|
||||||
|
{
|
||||||
|
if no_ref_mut_behind_and && r_mutbl == Mutability::Not {
|
||||||
pat_info.max_ref_mutbl = MutblCap::Not;
|
pat_info.max_ref_mutbl = MutblCap::Not;
|
||||||
}
|
}
|
||||||
|
|
||||||
(expected, r_ty)
|
(expected, r_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == pat_mutbl => (expected, r_ty),
|
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
let inner_ty = self.next_ty_var(inner.span);
|
let inner_ty = self.next_ty_var(inner.span);
|
||||||
let ref_ty = self.new_ref_ty(pat.span, pat_mutbl, inner_ty);
|
let ref_ty = self.new_ref_ty(pat.span, pat_mutbl, inner_ty);
|
||||||
|
9
tests/ui/pattern/no_ref_mut_behind_and.rs
Normal file
9
tests/ui/pattern/no_ref_mut_behind_and.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
//@ edition: 2021
|
||||||
|
//@ run-pass
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
#![feature(ref_pat_eat_one_layer_2024)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let &[[x]] = &[&mut [42]];
|
||||||
|
let _: &i32 = x;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user