diff options
| author | Nadrieril <nadrieril+git@gmail.com> | 2024-06-23 17:25:41 +0200 |
|---|---|---|
| committer | Nadrieril <nadrieril+git@gmail.com> | 2024-07-29 10:03:32 +0200 |
| commit | c7471664b356229cd9aac11f1c0339dcf24863b0 (patch) | |
| tree | 8bbfd76c1ec4ad09b351283908d9361e3b1ff5ad | |
| parent | cbdacec188b1d2ef18a074784edbe58be826be58 (diff) | |
| download | rust-c7471664b356229cd9aac11f1c0339dcf24863b0.tar.gz rust-c7471664b356229cd9aac11f1c0339dcf24863b0.zip | |
Visiting bindings is straightforward now
| -rw-r--r-- | compiler/rustc_mir_build/src/build/matches/mod.rs | 28 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/matches/util.rs | 53 |
2 files changed, 14 insertions, 67 deletions
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 78efa53253a..267db29ff3d 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -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, diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 79ee683d63c..d3ba1577edf 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -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 { |
