Remove the separate simplify step for match-pair trees
What remained of this simplification process has been integrated into construction of the match-pair trees.
This commit is contained in:
parent
854feae887
commit
e05df1cb5d
3 changed files with 14 additions and 71 deletions
|
@ -26,7 +26,6 @@ use crate::builder::{
|
|||
|
||||
// helper functions, broken out by category:
|
||||
mod match_pair;
|
||||
mod simplify;
|
||||
mod test;
|
||||
mod util;
|
||||
|
||||
|
@ -987,18 +986,16 @@ impl<'tcx> PatternExtraData<'tcx> {
|
|||
}
|
||||
|
||||
/// A pattern in a form suitable for lowering the match tree, with all irrefutable
|
||||
/// patterns simplified away, and or-patterns sorted to the end.
|
||||
/// patterns simplified away.
|
||||
///
|
||||
/// Here, "flat" indicates that the pattern's match pairs have been recursively
|
||||
/// simplified by [`Builder::simplify_match_pairs`]. They are not necessarily
|
||||
/// flat in an absolute sense.
|
||||
/// Here, "flat" indicates that irrefutable nodes in the pattern tree have been
|
||||
/// recursively replaced with their refutable subpatterns. They are not
|
||||
/// necessarily flat in an absolute sense.
|
||||
///
|
||||
/// Will typically be incorporated into a [`Candidate`].
|
||||
#[derive(Debug, Clone)]
|
||||
struct FlatPat<'tcx> {
|
||||
/// To match the pattern, all of these must be satisfied...
|
||||
// Invariant: all the match pairs are recursively simplified.
|
||||
// Invariant: or-patterns must be sorted to the end.
|
||||
match_pairs: Vec<MatchPairTree<'tcx>>,
|
||||
|
||||
extra_data: PatternExtraData<'tcx>,
|
||||
|
@ -1017,7 +1014,6 @@ impl<'tcx> FlatPat<'tcx> {
|
|||
is_never: pattern.is_never_pattern(),
|
||||
};
|
||||
MatchPairTree::for_pattern(place, pattern, cx, &mut match_pairs, &mut extra_data);
|
||||
cx.simplify_match_pairs(&mut match_pairs, &mut extra_data);
|
||||
|
||||
Self { match_pairs, extra_data }
|
||||
}
|
||||
|
@ -1124,7 +1120,7 @@ impl<'tcx> Candidate<'tcx> {
|
|||
|
||||
/// Incorporates an already-simplified [`FlatPat`] into a new candidate.
|
||||
fn from_flat_pat(flat_pat: FlatPat<'tcx>, has_guard: bool) -> Self {
|
||||
Candidate {
|
||||
let mut this = Candidate {
|
||||
match_pairs: flat_pat.match_pairs,
|
||||
extra_data: flat_pat.extra_data,
|
||||
has_guard,
|
||||
|
@ -1133,7 +1129,14 @@ impl<'tcx> Candidate<'tcx> {
|
|||
otherwise_block: None,
|
||||
pre_binding_block: None,
|
||||
false_edge_start_block: None,
|
||||
}
|
||||
};
|
||||
this.sort_match_pairs();
|
||||
this
|
||||
}
|
||||
|
||||
/// Restores the invariant that or-patterns must be sorted to the end.
|
||||
fn sort_match_pairs(&mut self) {
|
||||
self.match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. }));
|
||||
}
|
||||
|
||||
/// Returns whether the first match pair of this candidate is an or-pattern.
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
//! Simplifying Candidates
|
||||
//!
|
||||
//! *Simplifying* a match pair `place @ pattern` means breaking it down
|
||||
//! into bindings or other, simpler match pairs. For example:
|
||||
//!
|
||||
//! - `place @ (P1, P2)` can be simplified to `[place.0 @ P1, place.1 @ P2]`
|
||||
//! - `place @ x` can be simplified to `[]` by binding `x` to `place`
|
||||
//!
|
||||
//! The `simplify_match_pairs` routine just repeatedly applies these
|
||||
//! sort of simplifications until there is nothing left to
|
||||
//! simplify. Match pairs cannot be simplified if they require some
|
||||
//! sort of test: for example, testing which variant an enum is, or
|
||||
//! testing a value against a constant.
|
||||
|
||||
use std::mem;
|
||||
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::builder::Builder;
|
||||
use crate::builder::matches::{MatchPairTree, PatternExtraData, TestCase};
|
||||
|
||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
/// Simplify a list of match pairs so they all require a test. Stores relevant bindings and
|
||||
/// ascriptions in `extra_data`.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub(super) fn simplify_match_pairs(
|
||||
&mut self,
|
||||
match_pairs: &mut Vec<MatchPairTree<'tcx>>,
|
||||
extra_data: &mut PatternExtraData<'tcx>,
|
||||
) {
|
||||
// In order to please the borrow checker, in a pattern like `x @ pat` we must lower the
|
||||
// bindings in `pat` before `x`. E.g. (#69971):
|
||||
//
|
||||
// struct NonCopyStruct {
|
||||
// copy_field: u32,
|
||||
// }
|
||||
//
|
||||
// fn foo1(x: NonCopyStruct) {
|
||||
// let y @ NonCopyStruct { copy_field: z } = x;
|
||||
// // the above should turn into
|
||||
// let z = x.copy_field;
|
||||
// let y = x;
|
||||
// }
|
||||
//
|
||||
// We therefore lower bindings from left-to-right, except we lower the `x` in `x @ pat`
|
||||
// after any bindings in `pat`. This doesn't work for or-patterns: the current structure of
|
||||
// match lowering forces us to lower bindings inside or-patterns last.
|
||||
for mut match_pair in mem::take(match_pairs) {
|
||||
self.simplify_match_pairs(&mut match_pair.subpairs, extra_data);
|
||||
// Unsimplifiable pattern; we keep it.
|
||||
match_pairs.push(match_pair);
|
||||
}
|
||||
|
||||
// Move or-patterns to the end, because they can result in us
|
||||
// creating additional candidates, so we want to test them as
|
||||
// late as possible.
|
||||
match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. }));
|
||||
debug!(simplified = ?match_pairs, "simplify_match_pairs");
|
||||
}
|
||||
}
|
|
@ -763,7 +763,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let match_pair = candidate.match_pairs.remove(match_pair_index);
|
||||
candidate.match_pairs.extend(match_pair.subpairs);
|
||||
// Move or-patterns to the end.
|
||||
candidate.match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. }));
|
||||
candidate.sort_match_pairs();
|
||||
}
|
||||
|
||||
ret
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue