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