about summary refs log tree commit diff
path: root/compiler/rustc_mir_build
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2024-03-04 01:41:37 +0100
committerNadrieril <nadrieril+git@gmail.com>2024-06-16 18:30:26 +0200
commit764f086f2cd7cc4e2ca9c5fd9f53ba4c0b3a1740 (patch)
tree6dea43c3e2c7cd7aa3fa3ccce088192e6b6ea0d4 /compiler/rustc_mir_build
parent5fe2ca65cf5b2696d4d48c261cb7f6cecb2f7099 (diff)
downloadrust-764f086f2cd7cc4e2ca9c5fd9f53ba4c0b3a1740.tar.gz
rust-764f086f2cd7cc4e2ca9c5fd9f53ba4c0b3a1740.zip
Use `otherwise_block` for or-pattern shortcutting
Diffstat (limited to 'compiler/rustc_mir_build')
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs11
1 files changed, 8 insertions, 3 deletions
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index a67c59138cd..a5f24ba3e5b 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1585,18 +1585,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             // We could add them to the or-candidates before the call to `test_or_pattern` but this
             // would make it impossible to detect simplifiable or-patterns. That would guarantee
             // exponentially large CFGs for cases like `(1 | 2, 3 | 4, ...)`.
+            let mut last_otherwise = None;
+            first_candidate.visit_leaves(|leaf_candidate| {
+                last_otherwise = leaf_candidate.otherwise_block;
+            });
             first_candidate.visit_leaves(|leaf_candidate| {
                 assert!(leaf_candidate.match_pairs.is_empty());
                 leaf_candidate.match_pairs.extend(remaining_match_pairs.iter().cloned());
                 let or_start = leaf_candidate.pre_binding_block.unwrap();
                 // In a case like `(P | Q, R | S)`, if `P` succeeds and `R | S` fails, we know `(Q,
                 // R | S)` will fail too. If there is no guard, we skip testing of `Q` by branching
-                // directly to `remainder_start`. If there is a guard, `or_otherwise` can be reached
-                // by guard failure as well, so we can't skip `Q`.
+                // directly to `last_otherwise`. If there is a guard,
+                // `leaf_candidate.otherwise_block` can be reached by guard failure as well, so we
+                // can't skip `Q`.
                 let or_otherwise = if leaf_candidate.has_guard {
                     leaf_candidate.otherwise_block.unwrap()
                 } else {
-                    remainder_start
+                    last_otherwise.unwrap()
                 };
                 self.test_candidates_with_or(
                     span,