diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index 040d38c109b..8ff07c590bb 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -59,22 +59,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // // final bindings: [6, 7, 4, 5, 1, 2, 3] let mut accumulated_bindings = mem::take(candidate_bindings); - // Repeatedly simplify match pairs until fixed point is reached + let mut simplified_match_pairs = Vec::new(); + // Repeatedly simplify match pairs until we're left with only unsimplifiable ones. loop { - let mut changed = false; for match_pair in mem::take(match_pairs) { - match self.simplify_match_pair( + if let Err(match_pair) = self.simplify_match_pair( match_pair, candidate_bindings, candidate_ascriptions, match_pairs, ) { - Ok(()) => { - changed = true; - } - Err(match_pair) => { - match_pairs.push(match_pair); - } + simplified_match_pairs.push(match_pair); } } @@ -83,14 +78,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { mem::swap(candidate_bindings, &mut accumulated_bindings); candidate_bindings.clear(); - if !changed { - // If we were not able to simplify anymore, done. + if match_pairs.is_empty() { break; } } // 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 diff --git a/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir index 596dcef85fd..ea5cd55b560 100644 --- a/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir @@ -19,7 +19,8 @@ fn match_tuple(_1: (u32, bool, Option, u32)) -> u32 { bb0: { PlaceMention(_1); - switchInt((_1.0: u32)) -> [1: bb2, 4: bb2, otherwise: bb1]; + _2 = discriminant((_1.2: std::option::Option)); + switchInt(move _2) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { @@ -28,12 +29,11 @@ fn match_tuple(_1: (u32, bool, Option, u32)) -> u32 { } bb2: { - _2 = discriminant((_1.2: std::option::Option)); - switchInt(move _2) -> [0: bb4, 1: bb3, otherwise: bb1]; + switchInt((((_1.2: std::option::Option) as Some).0: i32)) -> [1: bb3, 8: bb3, otherwise: bb1]; } bb3: { - switchInt((((_1.2: std::option::Option) as Some).0: i32)) -> [1: bb4, 8: bb4, otherwise: bb1]; + switchInt((_1.0: u32)) -> [1: bb4, 4: bb4, otherwise: bb1]; } bb4: {