1
Fork 0

Store ByRef instead of BindingAnnotation in PatInfo

This commit is contained in:
Jules Bertholet 2024-04-16 19:05:17 -04:00
parent 6c6b3027ef
commit d19e48d79a
No known key found for this signature in database
GPG key ID: 32034DAFC38C1BFC
2 changed files with 30 additions and 30 deletions

View file

@ -707,6 +707,15 @@ pub enum ByRef {
No, No,
} }
impl ByRef {
pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
if let ByRef::Yes(old_mutbl) = &mut self {
*old_mutbl = cmp::min(*old_mutbl, mutbl);
}
self
}
}
/// Explicit binding annotations given in the HIR for a binding. Note /// Explicit binding annotations given in the HIR for a binding. Note
/// that this is not the final binding *mode* that we infer after type /// that this is not the final binding *mode* that we infer after type
/// inference. /// inference.
@ -732,13 +741,6 @@ impl BindingAnnotation {
Self::MUT_REF_MUT => "mut ref mut ", Self::MUT_REF_MUT => "mut ref mut ",
} }
} }
pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
if let ByRef::Yes(old_mutbl) = &mut self.0 {
*old_mutbl = cmp::min(*old_mutbl, mutbl);
}
self
}
} }
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]

View file

@ -79,7 +79,7 @@ struct TopInfo<'tcx> {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct PatInfo<'tcx, 'a> { struct PatInfo<'tcx, 'a> {
binding_mode: BindingAnnotation, binding_mode: ByRef,
max_ref_mutbl: Mutability, max_ref_mutbl: Mutability,
top_info: TopInfo<'tcx>, top_info: TopInfo<'tcx>,
decl_origin: Option<DeclOrigin<'a>>, decl_origin: Option<DeclOrigin<'a>>,
@ -125,8 +125,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
} }
} }
const INITIAL_BM: BindingAnnotation = BindingAnnotation(ByRef::No, Mutability::Not);
/// Mode for adjusting the expected type and binding mode. /// Mode for adjusting the expected type and binding mode.
enum AdjustMode { enum AdjustMode {
/// Peel off all immediate reference types. /// Peel off all immediate reference types.
@ -163,7 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) { ) {
let info = TopInfo { expected, origin_expr, span }; let info = TopInfo { expected, origin_expr, span };
let pat_info = PatInfo { let pat_info = PatInfo {
binding_mode: INITIAL_BM, binding_mode: ByRef::No,
max_ref_mutbl: Mutability::Mut, max_ref_mutbl: Mutability::Mut,
top_info: info, top_info: info,
decl_origin, decl_origin,
@ -296,43 +294,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self, &self,
pat: &'tcx Pat<'tcx>, pat: &'tcx Pat<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
def_bm: BindingAnnotation, def_br: ByRef,
adjust_mode: AdjustMode, adjust_mode: AdjustMode,
max_ref_mutbl: Mutability, max_ref_mutbl: Mutability,
) -> (Ty<'tcx>, BindingAnnotation, Mutability, bool) { ) -> (Ty<'tcx>, ByRef, Mutability, bool) {
if let ByRef::Yes(mutbl) = def_bm.0 { if let ByRef::Yes(mutbl) = def_br {
debug_assert!(mutbl <= max_ref_mutbl); debug_assert!(mutbl <= max_ref_mutbl);
} }
match adjust_mode { match adjust_mode {
AdjustMode::Pass => (expected, def_bm, max_ref_mutbl, false), AdjustMode::Pass => (expected, def_br, max_ref_mutbl, false),
AdjustMode::Reset => (expected, INITIAL_BM, Mutability::Mut, false), AdjustMode::Reset => (expected, ByRef::No, Mutability::Mut, false),
AdjustMode::ResetAndConsumeRef(ref_pat_mutbl) => { AdjustMode::ResetAndConsumeRef(ref_pat_mutbl) => {
let mutbls_match = def_bm.0 == ByRef::Yes(ref_pat_mutbl); let mutbls_match = def_br == ByRef::Yes(ref_pat_mutbl);
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
if mutbls_match { if mutbls_match {
debug!("consuming inherited reference"); debug!("consuming inherited reference");
(expected, INITIAL_BM, cmp::min(max_ref_mutbl, ref_pat_mutbl), true) (expected, ByRef::No, cmp::min(max_ref_mutbl, ref_pat_mutbl), true)
} else { } else {
let (new_ty, new_bm, max_ref_mutbl) = if ref_pat_mutbl == Mutability::Mut { let (new_ty, new_bm, max_ref_mutbl) = if ref_pat_mutbl == Mutability::Mut {
self.peel_off_references( self.peel_off_references(
pat, pat,
expected, expected,
def_bm, def_br,
Mutability::Not, Mutability::Not,
max_ref_mutbl, max_ref_mutbl,
) )
} else { } else {
(expected, def_bm.cap_ref_mutability(Mutability::Not), Mutability::Not) (expected, def_br.cap_ref_mutability(Mutability::Not), Mutability::Not)
}; };
(new_ty, new_bm, max_ref_mutbl, false) (new_ty, new_bm, max_ref_mutbl, false)
} }
} else { } else {
(expected, INITIAL_BM, max_ref_mutbl, mutbls_match) (expected, ByRef::No, max_ref_mutbl, mutbls_match)
} }
} }
AdjustMode::Peel => { AdjustMode::Peel => {
let peeled = let peeled =
self.peel_off_references(pat, expected, def_bm, Mutability::Mut, max_ref_mutbl); self.peel_off_references(pat, expected, def_br, Mutability::Mut, max_ref_mutbl);
(peeled.0, peeled.1, peeled.2, false) (peeled.0, peeled.1, peeled.2, false)
} }
} }
@ -413,10 +411,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self, &self,
pat: &'tcx Pat<'tcx>, pat: &'tcx Pat<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
mut def_bm: BindingAnnotation, mut def_br: ByRef,
max_peelable_mutability: Mutability, max_peelable_mutability: Mutability,
mut max_ref_mutability: Mutability, mut max_ref_mutability: Mutability,
) -> (Ty<'tcx>, BindingAnnotation, Mutability) { ) -> (Ty<'tcx>, ByRef, Mutability) {
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,
// for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
@ -437,7 +435,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat_adjustments.push(expected); pat_adjustments.push(expected);
expected = self.try_structurally_resolve_type(pat.span, inner_ty); expected = self.try_structurally_resolve_type(pat.span, inner_ty);
def_bm.0 = ByRef::Yes(match def_bm.0 { def_br = ByRef::Yes(match def_br {
// If default binding mode is by value, make it `ref` or `ref mut` // If default binding mode is by value, make it `ref` or `ref mut`
// (depending on whether we observe `&` or `&mut`). // (depending on whether we observe `&` or `&mut`).
ByRef::No | ByRef::No |
@ -450,21 +448,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
def_bm = def_bm.cap_ref_mutability(max_ref_mutability); def_br = def_br.cap_ref_mutability(max_ref_mutability);
if def_bm.0 == ByRef::Yes(Mutability::Not) { if def_br == ByRef::Yes(Mutability::Not) {
max_ref_mutability = Mutability::Not; max_ref_mutability = Mutability::Not;
} }
} }
if !pat_adjustments.is_empty() { if !pat_adjustments.is_empty() {
debug!("default binding mode is now {:?}", def_bm); debug!("default binding mode is now {:?}", def_br);
self.typeck_results self.typeck_results
.borrow_mut() .borrow_mut()
.pat_adjustments_mut() .pat_adjustments_mut()
.insert(pat.hir_id, pat_adjustments); .insert(pat.hir_id, pat_adjustments);
} }
(expected, def_bm, max_ref_mutability) (expected, def_br, max_ref_mutability)
} }
fn check_pat_lit( fn check_pat_lit(
@ -675,7 +673,7 @@ 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: BindingAnnotation(def_br, _), top_info: ti, .. } = pat_info; let PatInfo { binding_mode: def_br, top_info: ti, .. } = pat_info;
// Determine the binding mode... // Determine the binding mode...
let bm = match ba { let bm = match ba {