about summary refs log tree commit diff
path: root/compiler/rustc_mir_build/src/build/matches/simplify.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_build/src/build/matches/simplify.rs')
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs70
1 files changed, 20 insertions, 50 deletions
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index 53a5056cc3f..b5f0a97b28a 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -43,60 +43,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         //     let y = x;
         // }
         //
-        // We can't just reverse the binding order, because we must preserve pattern-order
-        // otherwise, e.g. in `let (Some(a), Some(b)) = (x, y)`. Our rule then is: deepest-first,
-        // and bindings at the same depth stay in source order.
-        //
-        // To do this, every time around the loop we prepend the newly found bindings to the
-        // bindings we already had.
-        //
-        // example:
-        // candidate.bindings = [1, 2, 3]
-        // bindings in iter 1: [4, 5]
-        // bindings in iter 2: [6, 7]
-        //
-        // final bindings: [6, 7, 4, 5, 1, 2, 3]
-        let mut accumulated_bindings = mem::take(candidate_bindings);
-        let mut simplified_match_pairs = Vec::new();
-        // Repeatedly simplify match pairs until we're left with only unsimplifiable ones.
-        loop {
-            for mut match_pair in mem::take(match_pairs) {
-                if let TestCase::Irrefutable { binding, ascription } = match_pair.test_case {
-                    if let Some(binding) = binding {
-                        candidate_bindings.push(binding);
-                    }
-                    if let Some(ascription) = ascription {
-                        candidate_ascriptions.push(ascription);
-                    }
-                    // Simplifiable pattern; we replace it with its subpairs and simplify further.
-                    match_pairs.append(&mut match_pair.subpairs);
-                } else {
-                    // Unsimplifiable pattern; we recursively simplify its subpairs and don't
-                    // process it further.
-                    self.simplify_match_pairs(
-                        &mut match_pair.subpairs,
-                        candidate_bindings,
-                        candidate_ascriptions,
-                    );
-                    simplified_match_pairs.push(match_pair);
+        // 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,
+                candidate_bindings,
+                candidate_ascriptions,
+            );
+            if let TestCase::Irrefutable { binding, ascription } = match_pair.test_case {
+                if let Some(binding) = binding {
+                    candidate_bindings.push(binding);
                 }
-            }
-
-            // This does: accumulated_bindings = candidate.bindings.take() ++ accumulated_bindings
-            candidate_bindings.extend_from_slice(&accumulated_bindings);
-            mem::swap(candidate_bindings, &mut accumulated_bindings);
-            candidate_bindings.clear();
-
-            if match_pairs.is_empty() {
-                break;
+                if let Some(ascription) = ascription {
+                    candidate_ascriptions.push(ascription);
+                }
+                // Simplifiable pattern; we replace it with its already simplified subpairs.
+                match_pairs.append(&mut match_pair.subpairs);
+            } else {
+                // Unsimplifiable pattern; we keep it.
+                match_pairs.push(match_pair);
             }
         }
 
-        // Store computed bindings back in `candidate_bindings`.
-        mem::swap(candidate_bindings, &mut accumulated_bindings);
-        // Store simplified match pairs back in `match_pairs`.
-        mem::swap(match_pairs, &mut simplified_match_pairs);
-
         // 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.