Visiting bindings is straightforward now
This commit is contained in:
parent
cbdacec188
commit
c7471664b3
2 changed files with 14 additions and 67 deletions
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue