mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Store Place
instead of PlaceBuilder
in MatchPair
This commit is contained in:
parent
3878b3716d
commit
14f186c756
@ -1106,7 +1106,10 @@ impl<'pat, 'tcx> TestCase<'pat, 'tcx> {
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct MatchPair<'pat, 'tcx> {
|
||||
/// This place...
|
||||
place: PlaceBuilder<'tcx>,
|
||||
// This can be `None` if it referred to a non-captured place in a closure.
|
||||
// Invariant: place.is_none() => test_case is Irrefutable
|
||||
// In other words this must be `Some(_)` after simplification.
|
||||
place: Option<Place<'tcx>>,
|
||||
|
||||
/// ... must pass this test...
|
||||
// Invariant: after creation and simplification in `Candidate::new()`, this must not be
|
||||
@ -1587,11 +1590,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
fn pick_test(
|
||||
&mut self,
|
||||
candidates: &mut [&mut Candidate<'_, 'tcx>],
|
||||
) -> (PlaceBuilder<'tcx>, Test<'tcx>) {
|
||||
) -> (Place<'tcx>, Test<'tcx>) {
|
||||
// Extract the match-pair from the highest priority candidate
|
||||
let match_pair = &candidates.first().unwrap().match_pairs[0];
|
||||
let test = self.test(match_pair);
|
||||
let match_place = match_pair.place.clone();
|
||||
// Unwrap is ok after simplification.
|
||||
let match_place = match_pair.place.unwrap();
|
||||
debug!(?test, ?match_pair);
|
||||
|
||||
(match_place, test)
|
||||
@ -1632,7 +1636,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
/// - candidate 1 becomes `[y @ false]` since we know that `x` was `false`.
|
||||
fn sort_candidates<'b, 'c, 'pat>(
|
||||
&mut self,
|
||||
match_place: &PlaceBuilder<'tcx>,
|
||||
match_place: Place<'tcx>,
|
||||
test: &Test<'tcx>,
|
||||
mut candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>],
|
||||
) -> (
|
||||
@ -1650,7 +1654,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// sorting.
|
||||
while let Some(candidate) = candidates.first_mut() {
|
||||
let Some(branch) =
|
||||
self.sort_candidate(&match_place, test, candidate, &target_candidates)
|
||||
self.sort_candidate(match_place, test, candidate, &target_candidates)
|
||||
else {
|
||||
break;
|
||||
};
|
||||
@ -1778,7 +1782,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// For each of the N possible test outcomes, build the vector of candidates that applies if
|
||||
// the test has that particular outcome.
|
||||
let (remaining_candidates, target_candidates) =
|
||||
self.sort_candidates(&match_place, &test, candidates);
|
||||
self.sort_candidates(match_place, &test, candidates);
|
||||
|
||||
// The block that we should branch to if none of the
|
||||
// `target_candidates` match.
|
||||
@ -1818,7 +1822,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
scrutinee_span,
|
||||
start_block,
|
||||
remainder_start,
|
||||
&match_place,
|
||||
match_place,
|
||||
&test,
|
||||
target_blocks,
|
||||
);
|
||||
|
@ -5,7 +5,6 @@
|
||||
// identify what tests are needed, perform the tests, and then filter
|
||||
// the candidates based on the result.
|
||||
|
||||
use crate::build::expr::as_place::PlaceBuilder;
|
||||
use crate::build::matches::{Candidate, MatchPair, Test, TestBranch, TestCase, TestKind};
|
||||
use crate::build::Builder;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
@ -55,18 +54,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
Test { span: match_pair.pattern.span, kind }
|
||||
}
|
||||
|
||||
#[instrument(skip(self, target_blocks, place_builder), level = "debug")]
|
||||
#[instrument(skip(self, target_blocks, place), level = "debug")]
|
||||
pub(super) fn perform_test(
|
||||
&mut self,
|
||||
match_start_span: Span,
|
||||
scrutinee_span: Span,
|
||||
block: BasicBlock,
|
||||
otherwise_block: BasicBlock,
|
||||
place_builder: &PlaceBuilder<'tcx>,
|
||||
place: Place<'tcx>,
|
||||
test: &Test<'tcx>,
|
||||
target_blocks: FxIndexMap<TestBranch<'tcx>, BasicBlock>,
|
||||
) {
|
||||
let place = place_builder.to_place(self);
|
||||
let place_ty = place.ty(&self.local_decls, self.tcx);
|
||||
debug!(?place, ?place_ty);
|
||||
let target_block = |branch| target_blocks.get(&branch).copied().unwrap_or(otherwise_block);
|
||||
@ -475,7 +473,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
/// tighter match code if we do something a bit different.
|
||||
pub(super) fn sort_candidate(
|
||||
&mut self,
|
||||
test_place: &PlaceBuilder<'tcx>,
|
||||
test_place: Place<'tcx>,
|
||||
test: &Test<'tcx>,
|
||||
candidate: &mut Candidate<'_, 'tcx>,
|
||||
sorted_candidates: &FxIndexMap<TestBranch<'tcx>, Vec<&mut Candidate<'_, 'tcx>>>,
|
||||
@ -486,8 +484,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))?;
|
||||
|
||||
let fully_matched;
|
||||
let ret = match (&test.kind, &match_pair.test_case) {
|
||||
@ -521,7 +522,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)
|
||||
|
@ -119,6 +119,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
place_builder = place_builder.project(ProjectionElem::OpaqueCast(pattern.ty));
|
||||
}
|
||||
|
||||
let place = place_builder.try_to_place(cx);
|
||||
let default_irrefutable = || TestCase::Irrefutable { binding: None, ascription: None };
|
||||
let mut subpairs = Vec::new();
|
||||
let test_case = match pattern.kind {
|
||||
@ -143,13 +144,13 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
..
|
||||
} => {
|
||||
// Apply the type ascription to the value at `match_pair.place`
|
||||
let ascription = place_builder.try_to_place(cx).map(|source| super::Ascription {
|
||||
let ascription = place.map(|source| super::Ascription {
|
||||
annotation: annotation.clone(),
|
||||
source,
|
||||
variance,
|
||||
});
|
||||
|
||||
subpairs.push(MatchPair::new(place_builder.clone(), subpattern, cx));
|
||||
subpairs.push(MatchPair::new(place_builder, subpattern, cx));
|
||||
TestCase::Irrefutable { ascription, binding: None }
|
||||
}
|
||||
|
||||
@ -162,7 +163,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
ref subpattern,
|
||||
is_primary: _,
|
||||
} => {
|
||||
let binding = place_builder.try_to_place(cx).map(|source| super::Binding {
|
||||
let binding = place.map(|source| super::Binding {
|
||||
span: pattern.span,
|
||||
source,
|
||||
var_id: var,
|
||||
@ -171,14 +172,14 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
|
||||
if let Some(subpattern) = subpattern.as_ref() {
|
||||
// this is the `x @ P` case; have to keep matching against `P` now
|
||||
subpairs.push(MatchPair::new(place_builder.clone(), subpattern, cx));
|
||||
subpairs.push(MatchPair::new(place_builder, subpattern, cx));
|
||||
}
|
||||
TestCase::Irrefutable { ascription: None, binding }
|
||||
}
|
||||
|
||||
PatKind::InlineConstant { subpattern: ref pattern, def, .. } => {
|
||||
// Apply a type ascription for the inline constant to the value at `match_pair.place`
|
||||
let ascription = place_builder.try_to_place(cx).map(|source| {
|
||||
let ascription = place.map(|source| {
|
||||
let span = pattern.span;
|
||||
let parent_id = cx.tcx.typeck_root_def_id(cx.def_id.to_def_id());
|
||||
let args = ty::InlineConstArgs::new(
|
||||
@ -204,7 +205,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
super::Ascription { annotation, source, variance: ty::Contravariant }
|
||||
});
|
||||
|
||||
subpairs.push(MatchPair::new(place_builder.clone(), pattern, cx));
|
||||
subpairs.push(MatchPair::new(place_builder, pattern, cx));
|
||||
TestCase::Irrefutable { ascription, binding: None }
|
||||
}
|
||||
|
||||
@ -226,7 +227,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
}
|
||||
|
||||
PatKind::Variant { adt_def, variant_index, args, ref subpatterns } => {
|
||||
let downcast_place = place_builder.clone().downcast(adt_def, variant_index); // `(x as Variant)`
|
||||
let downcast_place = place_builder.downcast(adt_def, variant_index); // `(x as Variant)`
|
||||
subpairs = cx.field_match_pairs(downcast_place, subpatterns);
|
||||
|
||||
let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
|
||||
@ -248,13 +249,12 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
}
|
||||
|
||||
PatKind::Leaf { ref subpatterns } => {
|
||||
subpairs = cx.field_match_pairs(place_builder.clone(), subpatterns);
|
||||
subpairs = cx.field_match_pairs(place_builder, subpatterns);
|
||||
default_irrefutable()
|
||||
}
|
||||
|
||||
PatKind::Deref { ref subpattern } => {
|
||||
let place_builder = place_builder.clone().deref();
|
||||
subpairs.push(MatchPair::new(place_builder, subpattern, cx));
|
||||
subpairs.push(MatchPair::new(place_builder.deref(), subpattern, cx));
|
||||
default_irrefutable()
|
||||
}
|
||||
|
||||
@ -265,7 +265,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
MatchPair { place: place_builder, test_case, subpairs, pattern }
|
||||
MatchPair { place, test_case, subpairs, pattern }
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,8 +311,8 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
|
||||
}
|
||||
} else {
|
||||
// Insert a Shallow borrow of any place that is switched on.
|
||||
if let Some(resolved_place) = match_pair.place.try_to_place(self.cx) {
|
||||
self.fake_borrows.insert(resolved_place);
|
||||
if let Some(place) = match_pair.place {
|
||||
self.fake_borrows.insert(place);
|
||||
}
|
||||
|
||||
for subpair in &match_pair.subpairs {
|
||||
|
Loading…
Reference in New Issue
Block a user