about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZalathar <Zalathar@users.noreply.github.com>2024-07-07 23:29:18 +1000
committerZalathar <Zalathar@users.noreply.github.com>2024-07-16 11:51:52 +1000
commite37b92ffd8b0fa490566416fbf6d0479734a8b83 (patch)
tree2e759a790652914c25ee5eaf8eb426898a9aed54
parent00167abb4148d11476b0ebc127b769e0366be660 (diff)
downloadrust-e37b92ffd8b0fa490566416fbf6d0479734a8b83.tar.gz
rust-e37b92ffd8b0fa490566416fbf6d0479734a8b83.zip
Use an iterator to find `expand_until`
This makes it easier to see that the split point is always the index after the
found item, or the whole list if no stopping point was found.
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs33
1 files changed, 19 insertions, 14 deletions
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 841ef2719c9..7ad453be365 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1536,10 +1536,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         start_block: BasicBlock,
         candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>],
     ) -> BlockAnd<&'b mut [&'c mut Candidate<'pat, 'tcx>]> {
-        // We can't expand or-patterns freely. The rule is: if the candidate has an
-        // or-pattern as its only remaining match pair, we can expand it freely. If it has
-        // other match pairs, we can expand it but we can't process more candidates after
-        // it.
+        // We can't expand or-patterns freely. The rule is:
+        // - If a candidate doesn't start with an or-pattern, we include it in
+        //   the expansion list as-is (i.e. it "expands" to itself).
+        // - If a candidate has an or-pattern as its only remaining match pair,
+        //   we can expand it.
+        // - If it starts with an or-pattern but also has other match pairs,
+        //   we can expand it, but we can't process more candidates after it.
         //
         // If we didn't stop, the `otherwise` cases could get mixed up. E.g. in the
         // following, or-pattern simplification (in `merge_trivial_subcandidates`) makes it
@@ -1556,17 +1559,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // }
         // ```
         //
-        // We therefore split the `candidates` slice in two, expand or-patterns in the first half,
+        // We therefore split the `candidates` slice in two, expand or-patterns in the first part,
         // and process the rest separately.
-        let mut expand_until = 0;
-        for (i, candidate) in candidates.iter().enumerate() {
-            expand_until = i + 1;
-            if candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern() {
-                // The candidate has an or-pattern as well as more match pairs: we must
-                // split the candidates list here.
-                break;
-            }
-        }
+        let expand_until = candidates
+            .iter()
+            .position(|candidate| {
+                // If a candidate starts with an or-pattern and has more match pairs,
+                // we can expand it, but we must stop expanding _after_ it.
+                candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern()
+            })
+            .map(|pos| pos + 1) // Stop _after_ the found candidate
+            .unwrap_or(candidates.len()); // Otherwise, include all candidates
         let (candidates_to_expand, remaining_candidates) = candidates.split_at_mut(expand_until);
 
         // Expand one level of or-patterns for each candidate in `candidates_to_expand`.
@@ -1581,6 +1584,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     expanded_candidates.push(subcandidate);
                 }
             } else {
+                // A candidate that doesn't start with an or-pattern has nothing to
+                // expand, so it is included in the post-expansion list as-is.
                 expanded_candidates.push(candidate);
             }
         }