Rollup merge of #138959 - meithecatte:matchpair-place-option, r=Zalathar
Revert "Make MatchPairTree::place non-optional" Reverts a part of #137875. Fixes #138958. cc `@Zalathar`
This commit is contained in:
commit
33c90235a1
5 changed files with 34 additions and 9 deletions
|
@ -115,7 +115,6 @@ impl<'tcx> MatchPairTree<'tcx> {
|
|||
place_builder = place_builder.project(ProjectionElem::OpaqueCast(pattern.ty));
|
||||
}
|
||||
|
||||
// Place can be none if the pattern refers to a non-captured place in a closure.
|
||||
let place = place_builder.try_to_place(cx);
|
||||
let mut subpairs = Vec::new();
|
||||
let test_case = match pattern.kind {
|
||||
|
@ -321,7 +320,7 @@ impl<'tcx> MatchPairTree<'tcx> {
|
|||
if let Some(test_case) = test_case {
|
||||
// This pattern is refutable, so push a new match-pair node.
|
||||
match_pairs.push(MatchPairTree {
|
||||
place: place.expect("refutable patterns should always have a place to inspect"),
|
||||
place,
|
||||
test_case,
|
||||
subpairs,
|
||||
pattern_ty: pattern.ty,
|
||||
|
|
|
@ -1279,7 +1279,13 @@ impl<'tcx> TestCase<'tcx> {
|
|||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct MatchPairTree<'tcx> {
|
||||
/// This place...
|
||||
place: Place<'tcx>,
|
||||
///
|
||||
/// ---
|
||||
/// This can be `None` if it referred to a non-captured place in a closure.
|
||||
///
|
||||
/// Invariant: Can only be `None` when `test_case` is `Or`.
|
||||
/// Therefore this must be `Some(_)` after or-pattern expansion.
|
||||
place: Option<Place<'tcx>>,
|
||||
|
||||
/// ... must pass this test...
|
||||
test_case: TestCase<'tcx>,
|
||||
|
@ -2099,9 +2105,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// Extract the match-pair from the highest priority candidate
|
||||
let match_pair = &candidates[0].match_pairs[0];
|
||||
let test = self.pick_test_for_match_pair(match_pair);
|
||||
// Unwrap is ok after simplification.
|
||||
let match_place = match_pair.place.unwrap();
|
||||
debug!(?test, ?match_pair);
|
||||
|
||||
(match_pair.place, test)
|
||||
(match_place, test)
|
||||
}
|
||||
|
||||
/// Given a test, we partition the input candidates into several buckets.
|
||||
|
|
|
@ -470,8 +470,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// than one, but it'd be very unusual to have two sides that
|
||||
// both require tests; you'd expect one side to be simplified
|
||||
// away.)
|
||||
let (match_pair_index, match_pair) =
|
||||
candidate.match_pairs.iter().enumerate().find(|&(_, mp)| mp.place == test_place)?;
|
||||
let (match_pair_index, match_pair) = candidate
|
||||
.match_pairs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|&(_, mp)| mp.place == Some(test_place))?;
|
||||
|
||||
// If true, the match pair is completely entailed by its corresponding test
|
||||
// branch, so it can be removed. If false, the match pair is _compatible_
|
||||
|
@ -514,7 +517,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
candidate
|
||||
.match_pairs
|
||||
.iter()
|
||||
.any(|mp| mp.place == test_place && is_covering_range(&mp.test_case))
|
||||
.any(|mp| mp.place == Some(test_place) && is_covering_range(&mp.test_case))
|
||||
};
|
||||
if sorted_candidates
|
||||
.get(&TestBranch::Failure)
|
||||
|
|
|
@ -173,10 +173,14 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
|
|||
// }
|
||||
// ```
|
||||
// Hence we fake borrow using a deep borrow.
|
||||
self.fake_borrow(match_pair.place, FakeBorrowKind::Deep);
|
||||
if let Some(place) = match_pair.place {
|
||||
self.fake_borrow(place, FakeBorrowKind::Deep);
|
||||
}
|
||||
} else {
|
||||
// Insert a Shallow borrow of any place that is switched on.
|
||||
self.fake_borrow(match_pair.place, FakeBorrowKind::Shallow);
|
||||
if let Some(place) = match_pair.place {
|
||||
self.fake_borrow(place, FakeBorrowKind::Shallow);
|
||||
}
|
||||
|
||||
for subpair in &match_pair.subpairs {
|
||||
self.visit_match_pair(subpair);
|
||||
|
|
11
tests/ui/closures/upvar-or-pattern-issue-138958.rs
Normal file
11
tests/ui/closures/upvar-or-pattern-issue-138958.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
//@ edition:2024
|
||||
//@ check-pass
|
||||
|
||||
pub fn f(x: (u32, u32)) {
|
||||
let _ = || {
|
||||
let ((0, a) | (a, _)) = x;
|
||||
a
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue