|
| 1 | +use std::marker::PhantomData; |
| 2 | + |
1 | 3 | use crate::build::expr::as_place::{PlaceBase, PlaceBuilder};
|
2 | 4 | use crate::build::matches::{Binding, Candidate, FlatPat, MatchPair, TestCase};
|
3 | 5 | use crate::build::Builder;
|
@@ -269,18 +271,6 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
269 | 271 | }
|
270 | 272 | }
|
271 | 273 |
|
272 |
| -pub(super) struct FakeBorrowCollector<'a, 'b, 'tcx> { |
273 |
| - cx: &'a mut Builder<'b, 'tcx>, |
274 |
| - /// Base of the scrutinee place. Used to distinguish bindings inside the scrutinee place from |
275 |
| - /// bindings inside deref patterns. |
276 |
| - scrutinee_base: PlaceBase, |
277 |
| - /// Store for each place the kind of borrow to take. In case of conflicts, we take the strongest |
278 |
| - /// borrow (i.e. Deep > Shallow). |
279 |
| - /// Invariant: for any place in `fake_borrows`, all the prefixes of this place that are |
280 |
| - /// dereferences are also borrowed with the same of stronger borrow kind. |
281 |
| - fake_borrows: FxIndexMap<Place<'tcx>, FakeBorrowKind>, |
282 |
| -} |
283 |
| - |
284 | 274 | /// Determine the set of places that have to be stable across match guards.
|
285 | 275 | ///
|
286 | 276 | /// Returns a list of places that need a fake borrow along with a local to store it.
|
@@ -344,6 +334,18 @@ pub(super) fn collect_fake_borrows<'tcx>(
|
344 | 334 | .collect()
|
345 | 335 | }
|
346 | 336 |
|
| 337 | +pub(super) struct FakeBorrowCollector<'a, 'b, 'tcx> { |
| 338 | + cx: &'a mut Builder<'b, 'tcx>, |
| 339 | + /// Base of the scrutinee place. Used to distinguish bindings inside the scrutinee place from |
| 340 | + /// bindings inside deref patterns. |
| 341 | + scrutinee_base: PlaceBase, |
| 342 | + /// Store for each place the kind of borrow to take. In case of conflicts, we take the strongest |
| 343 | + /// borrow (i.e. Deep > Shallow). |
| 344 | + /// Invariant: for any place in `fake_borrows`, all the prefixes of this place that are |
| 345 | + /// dereferences are also borrowed with the same of stronger borrow kind. |
| 346 | + fake_borrows: FxIndexMap<Place<'tcx>, FakeBorrowKind>, |
| 347 | +} |
| 348 | + |
347 | 349 | impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
|
348 | 350 | // Fake borrow this place and its dereference prefixes.
|
349 | 351 | fn fake_borrow(&mut self, place: Place<'tcx>, kind: FakeBorrowKind) {
|
@@ -457,6 +459,57 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
|
457 | 459 | }
|
458 | 460 | }
|
459 | 461 |
|
| 462 | +/// Visit all the bindings of these candidates. Because or-alternatives bind the same variables, we |
| 463 | +/// only explore the first one of each or-pattern. |
| 464 | +pub(super) fn visit_bindings<'tcx>( |
| 465 | + candidates: &[&mut Candidate<'_, 'tcx>], |
| 466 | + f: impl FnMut(&Binding<'tcx>), |
| 467 | +) { |
| 468 | + let mut visitor = BindingsVisitor { f, phantom: PhantomData }; |
| 469 | + for candidate in candidates.iter() { |
| 470 | + visitor.visit_candidate(candidate); |
| 471 | + } |
| 472 | +} |
| 473 | + |
| 474 | +pub(super) struct BindingsVisitor<'tcx, F> { |
| 475 | + f: F, |
| 476 | + phantom: PhantomData<&'tcx ()>, |
| 477 | +} |
| 478 | + |
| 479 | +impl<'tcx, F> BindingsVisitor<'tcx, F> |
| 480 | +where |
| 481 | + F: FnMut(&Binding<'tcx>), |
| 482 | +{ |
| 483 | + fn visit_candidate(&mut self, candidate: &Candidate<'_, 'tcx>) { |
| 484 | + for binding in &candidate.extra_data.bindings { |
| 485 | + (self.f)(binding) |
| 486 | + } |
| 487 | + for match_pair in &candidate.match_pairs { |
| 488 | + self.visit_match_pair(match_pair); |
| 489 | + } |
| 490 | + } |
| 491 | + |
| 492 | + fn visit_flat_pat(&mut self, flat_pat: &FlatPat<'_, 'tcx>) { |
| 493 | + for binding in &flat_pat.extra_data.bindings { |
| 494 | + (self.f)(binding) |
| 495 | + } |
| 496 | + for match_pair in &flat_pat.match_pairs { |
| 497 | + self.visit_match_pair(match_pair); |
| 498 | + } |
| 499 | + } |
| 500 | + |
| 501 | + fn visit_match_pair(&mut self, match_pair: &MatchPair<'_, 'tcx>) { |
| 502 | + if let TestCase::Or { pats, .. } = &match_pair.test_case { |
| 503 | + // All the or-alternatives should bind the same locals, so we only visit the first one. |
| 504 | + self.visit_flat_pat(&pats[0]) |
| 505 | + } else { |
| 506 | + for subpair in &match_pair.subpairs { |
| 507 | + self.visit_match_pair(subpair); |
| 508 | + } |
| 509 | + } |
| 510 | + } |
| 511 | +} |
| 512 | + |
460 | 513 | #[must_use]
|
461 | 514 | pub(crate) fn ref_pat_borrow_kind(ref_mutability: Mutability) -> BorrowKind {
|
462 | 515 | match ref_mutability {
|
|
0 commit comments