Visiting bindings is straightforward now

This commit is contained in:
Nadrieril 2024-06-23 17:25:41 +02:00
parent cbdacec188
commit c7471664b3
2 changed files with 14 additions and 67 deletions

View file

@ -17,7 +17,6 @@ use rustc_span::symbol::Symbol;
use rustc_span::{BytePos, Pos, Span};
use rustc_target::abi::VariantIdx;
use tracing::{debug, instrument};
use util::visit_bindings;
use crate::build::expr::as_place::PlaceBuilder;
use crate::build::scope::DropKind;
@ -701,7 +700,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
initializer: PlaceBuilder<'tcx>,
set_match_place: bool,
) -> BlockAnd<()> {
let mut candidate = Candidate::new(initializer.clone(), irrefutable_pat, false, self);
let candidate = Candidate::new(initializer.clone(), irrefutable_pat, false, self);
let built_tree = self.lower_match_tree(
block,
irrefutable_pat.span,
&initializer,
irrefutable_pat.span,
vec![candidate],
false,
);
let [branch] = built_tree.branches.try_into().unwrap();
// For matches and function arguments, the place that is being matched
// can be set when creating the variables. But the place for
@ -722,7 +730,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// };
// ```
if let Some(place) = initializer.try_to_place(self) {
visit_bindings(&[&mut candidate], |binding: &Binding<'_>| {
// Because or-alternatives bind the same variables, we only explore the first one.
let first_sub_branch = branch.sub_branches.first().unwrap();
for binding in &first_sub_branch.bindings {
let local = self.var_local_id(binding.var_id, OutsideGuard);
if let LocalInfo::User(BindingForm::Var(VarBindingForm {
opt_match_place: Some((ref mut match_place, _)),
@ -733,20 +743,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} else {
bug!("Let binding to non-user variable.")
};
});
}
}
}
let built_tree = self.lower_match_tree(
block,
irrefutable_pat.span,
&initializer,
irrefutable_pat.span,
vec![candidate],
false,
);
let [branch] = built_tree.branches.try_into().unwrap();
self.bind_pattern(
self.source_info(irrefutable_pat.span),
branch,

View file

@ -1,5 +1,3 @@
use std::marker::PhantomData;
use rustc_data_structures::fx::FxIndexMap;
use rustc_middle::mir::*;
use rustc_middle::ty::Ty;
@ -221,57 +219,6 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
}
}
/// Visit all the bindings of these candidates. Because or-alternatives bind the same variables, we
/// only explore the first one of each or-pattern.
pub(super) fn visit_bindings<'tcx>(
candidates: &[&mut Candidate<'_, 'tcx>],
f: impl FnMut(&Binding<'tcx>),
) {
let mut visitor = BindingsVisitor { f, phantom: PhantomData };
for candidate in candidates.iter() {
visitor.visit_candidate(candidate);
}
}
pub(super) struct BindingsVisitor<'tcx, F> {
f: F,
phantom: PhantomData<&'tcx ()>,
}
impl<'tcx, F> BindingsVisitor<'tcx, F>
where
F: FnMut(&Binding<'tcx>),
{
fn visit_candidate(&mut self, candidate: &Candidate<'_, 'tcx>) {
for binding in &candidate.extra_data.bindings {
(self.f)(binding)
}
for match_pair in &candidate.match_pairs {
self.visit_match_pair(match_pair);
}
}
fn visit_flat_pat(&mut self, flat_pat: &FlatPat<'_, 'tcx>) {
for binding in &flat_pat.extra_data.bindings {
(self.f)(binding)
}
for match_pair in &flat_pat.match_pairs {
self.visit_match_pair(match_pair);
}
}
fn visit_match_pair(&mut self, match_pair: &MatchPairTree<'_, 'tcx>) {
if let TestCase::Or { pats, .. } = &match_pair.test_case {
// All the or-alternatives should bind the same locals, so we only visit the first one.
self.visit_flat_pat(&pats[0])
} else {
for subpair in &match_pair.subpairs {
self.visit_match_pair(subpair);
}
}
}
}
#[must_use]
pub(crate) fn ref_pat_borrow_kind(ref_mutability: Mutability) -> BorrowKind {
match ref_mutability {