about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZalathar <Zalathar@users.noreply.github.com>2025-03-05 23:26:00 +1100
committerZalathar <Zalathar@users.noreply.github.com>2025-03-05 23:26:00 +1100
commite05df1cb5d13200314e95dde3e0f497d6c5a38aa (patch)
tree3dde249de54a110d01122bc7fcfff9fd8722b14c
parent854feae88773da49f2b1a900f46668938cf52b85 (diff)
downloadrust-e05df1cb5d13200314e95dde3e0f497d6c5a38aa.tar.gz
rust-e05df1cb5d13200314e95dde3e0f497d6c5a38aa.zip
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.
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/mod.rs23
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/simplify.rs60
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/test.rs2
3 files changed, 14 insertions, 71 deletions
diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs
index bb93482c0b6..5d97bf13f86 100644
--- a/compiler/rustc_mir_build/src/builder/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs
@@ -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.
diff --git a/compiler/rustc_mir_build/src/builder/matches/simplify.rs b/compiler/rustc_mir_build/src/builder/matches/simplify.rs
deleted file mode 100644
index 5965b35b70c..00000000000
--- a/compiler/rustc_mir_build/src/builder/matches/simplify.rs
+++ /dev/null
@@ -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");
-    }
-}
diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs
index fe5ec32422c..f92036a83e1 100644
--- a/compiler/rustc_mir_build/src/builder/matches/test.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/test.rs
@@ -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