diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 35f5a6bfac5f4..81a1d3acb06cc 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1207,53 +1207,43 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, span: Span, scrutinee_span: Span, - start_block: BasicBlock, + mut start_block: BasicBlock, otherwise_block: BasicBlock, candidates: &mut [&mut Candidate<'_, 'tcx>], fake_borrows: &mut Option>>, ) { - // The candidates are sorted by priority. Check to see whether the - // higher priority candidates (and hence at the front of the slice) - // have satisfied all their match pairs. - let fully_matched = candidates.iter().take_while(|c| c.match_pairs.is_empty()).count(); - debug!("match_candidates: {:?} candidates fully matched", fully_matched); - let (matched_candidates, unmatched_candidates) = candidates.split_at_mut(fully_matched); - - let block = if !matched_candidates.is_empty() { - let otherwise_block = - self.select_matched_candidates(matched_candidates, start_block, fake_borrows); - - if let Some(last_otherwise_block) = otherwise_block { - last_otherwise_block - } else { - // Any remaining candidates are unreachable. - if unmatched_candidates.is_empty() { - return; - } - self.cfg.start_new_block() + match candidates { + [] => { + // If there are no candidates that still need testing, we're done. Since all matches are + // exhaustive, execution should never reach this point. + let source_info = self.source_info(span); + self.cfg.goto(start_block, source_info, otherwise_block); + } + [first, remaining @ ..] if first.match_pairs.is_empty() => { + // The first candidate has satisfied all its match pairs; we link it up and continue + // with the remaining candidates. + start_block = self.select_matched_candidate(first, start_block, fake_borrows); + self.match_simplified_candidates( + span, + scrutinee_span, + start_block, + otherwise_block, + remaining, + fake_borrows, + ) + } + candidates => { + // The first candidate has some unsatisfied match pairs; we proceed to do more tests. + self.test_candidates_with_or( + span, + scrutinee_span, + candidates, + start_block, + otherwise_block, + fake_borrows, + ); } - } else { - start_block - }; - - // If there are no candidates that still need testing, we're - // done. Since all matches are exhaustive, execution should - // never reach this point. - if unmatched_candidates.is_empty() { - let source_info = self.source_info(span); - self.cfg.goto(block, source_info, otherwise_block); - return; } - - // Test for the remaining candidates. - self.test_candidates_with_or( - span, - scrutinee_span, - unmatched_candidates, - block, - otherwise_block, - fake_borrows, - ); } /// Link up matched candidates. @@ -1275,47 +1265,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// * the [otherwise block] of the third pattern to a block with an /// [`Unreachable` terminator](TerminatorKind::Unreachable). /// - /// In addition, we add fake edges from the otherwise blocks to the + /// In addition, we later add fake edges from the otherwise blocks to the /// pre-binding block of the next candidate in the original set of /// candidates. /// /// [pre-binding block]: Candidate::pre_binding_block /// [otherwise block]: Candidate::otherwise_block - fn select_matched_candidates( + fn select_matched_candidate( &mut self, - matched_candidates: &mut [&mut Candidate<'_, 'tcx>], + candidate: &mut Candidate<'_, 'tcx>, start_block: BasicBlock, fake_borrows: &mut Option>>, - ) -> Option { - debug_assert!( - !matched_candidates.is_empty(), - "select_matched_candidates called with no candidates", - ); - debug_assert!( - matched_candidates.iter().all(|c| c.subcandidates.is_empty()), - "subcandidates should be empty in select_matched_candidates", - ); + ) -> BasicBlock { + assert!(candidate.otherwise_block.is_none()); + assert!(candidate.pre_binding_block.is_none()); + assert!(candidate.subcandidates.is_empty()); - // Insert a borrows of prefixes of places that are bound and are - // behind a dereference projection. - // - // These borrows are taken to avoid situations like the following: - // - // match x[10] { - // _ if { x = &[0]; false } => (), - // y => (), // Out of bounds array access! - // } - // - // match *x { - // // y is bound by reference in the guard and then by copy in the - // // arm, so y is 2 in the arm! - // y if { y == 1 && (x = &2) == () } => y, - // _ => 3, - // } if let Some(fake_borrows) = fake_borrows { - for Binding { source, .. } in - matched_candidates.iter().flat_map(|candidate| &candidate.bindings) - { + // Insert a borrows of prefixes of places that are bound and are + // behind a dereference projection. + // + // These borrows are taken to avoid situations like the following: + // + // match x[10] { + // _ if { x = &[0]; false } => (), + // y => (), // Out of bounds array access! + // } + // + // match *x { + // // y is bound by reference in the guard and then by copy in the + // // arm, so y is 2 in the arm! + // y if { y == 1 && (x = &2) == () } => y, + // _ => 3, + // } + for Binding { source, .. } in &candidate.bindings { if let Some(i) = source.projection.iter().rposition(|elem| elem == ProjectionElem::Deref) { @@ -1329,38 +1312,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - let fully_matched_with_guard = matched_candidates - .iter() - .position(|c| !c.has_guard) - .unwrap_or(matched_candidates.len() - 1); - - let (reachable_candidates, unreachable_candidates) = - matched_candidates.split_at_mut(fully_matched_with_guard + 1); - - let mut next_prebinding = start_block; - - for candidate in reachable_candidates.iter_mut() { - assert!(candidate.otherwise_block.is_none()); - assert!(candidate.pre_binding_block.is_none()); - candidate.pre_binding_block = Some(next_prebinding); - if candidate.has_guard { - // Create the otherwise block for this candidate, which is the - // pre-binding block for the next candidate. - next_prebinding = self.cfg.start_new_block(); - candidate.otherwise_block = Some(next_prebinding); - } - } - - debug!( - "match_candidates: add pre_binding_blocks for unreachable {:?}", - unreachable_candidates, - ); - for candidate in unreachable_candidates { - assert!(candidate.pre_binding_block.is_none()); - candidate.pre_binding_block = Some(self.cfg.start_new_block()); + candidate.pre_binding_block = Some(start_block); + let otherwise_block = self.cfg.start_new_block(); + if candidate.has_guard { + // Create the otherwise block for this candidate, which is the + // pre-binding block for the next candidate. + candidate.otherwise_block = Some(otherwise_block); } - - reachable_candidates.last_mut().unwrap().otherwise_block + otherwise_block } /// Tests a candidate where there are only or-patterns left to test, or diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir index 028d7ee7cd868..19a777cb03bc7 100644 --- a/tests/mir-opt/building/issue_101867.main.built.after.mir +++ b/tests/mir-opt/building/issue_101867.main.built.after.mir @@ -27,13 +27,13 @@ fn main() -> () { StorageLive(_5); PlaceMention(_1); _6 = discriminant(_1); - switchInt(move _6) -> [1: bb5, otherwise: bb4]; + switchInt(move _6) -> [1: bb6, otherwise: bb4]; } bb1: { StorageLive(_3); StorageLive(_4); - _4 = begin_panic::<&str>(const "explicit panic") -> bb8; + _4 = begin_panic::<&str>(const "explicit panic") -> bb10; } bb2: { @@ -48,14 +48,22 @@ fn main() -> () { } bb4: { - goto -> bb7; + goto -> bb9; } bb5: { - falseEdge -> [real: bb6, imaginary: bb4]; + goto -> bb3; } bb6: { + falseEdge -> [real: bb8, imaginary: bb4]; + } + + bb7: { + goto -> bb4; + } + + bb8: { _5 = ((_1 as Some).0: u8); _0 = const (); StorageDead(_5); @@ -63,12 +71,12 @@ fn main() -> () { return; } - bb7: { + bb9: { StorageDead(_5); goto -> bb1; } - bb8 (cleanup): { + bb10 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/issue_49232.main.built.after.mir b/tests/mir-opt/building/issue_49232.main.built.after.mir index 7c1f5a6ec72d5..d09a1748a8b36 100644 --- a/tests/mir-opt/building/issue_49232.main.built.after.mir +++ b/tests/mir-opt/building/issue_49232.main.built.after.mir @@ -17,7 +17,7 @@ fn main() -> () { } bb1: { - falseUnwind -> [real: bb2, unwind: bb12]; + falseUnwind -> [real: bb2, unwind: bb14]; } bb2: { @@ -25,7 +25,7 @@ fn main() -> () { StorageLive(_3); _3 = const true; PlaceMention(_3); - switchInt(_3) -> [0: bb4, otherwise: bb5]; + switchInt(_3) -> [0: bb4, otherwise: bb6]; } bb3: { @@ -34,37 +34,45 @@ fn main() -> () { } bb4: { - falseEdge -> [real: bb6, imaginary: bb5]; + falseEdge -> [real: bb8, imaginary: bb6]; } bb5: { - _0 = const (); - goto -> bb11; + goto -> bb3; } bb6: { - _2 = const 4_i32; - goto -> bb9; + _0 = const (); + goto -> bb13; } bb7: { - unreachable; + goto -> bb3; } bb8: { - goto -> bb9; + _2 = const 4_i32; + goto -> bb11; } bb9: { + unreachable; + } + + bb10: { + goto -> bb11; + } + + bb11: { FakeRead(ForLet(None), _2); StorageDead(_3); StorageLive(_5); StorageLive(_6); _6 = &_2; - _5 = std::mem::drop::<&i32>(move _6) -> [return: bb10, unwind: bb12]; + _5 = std::mem::drop::<&i32>(move _6) -> [return: bb12, unwind: bb14]; } - bb10: { + bb12: { StorageDead(_6); StorageDead(_5); _1 = const (); @@ -72,13 +80,13 @@ fn main() -> () { goto -> bb1; } - bb11: { + bb13: { StorageDead(_3); StorageDead(_2); return; } - bb12 (cleanup): { + bb14 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir index d7c758d8876aa..89572177b1d28 100644 --- a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir +++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir @@ -19,13 +19,13 @@ fn test_complex() -> () { bb0: { StorageLive(_1); StorageLive(_2); - _2 = E::f() -> [return: bb1, unwind: bb33]; + _2 = E::f() -> [return: bb1, unwind: bb37]; } bb1: { PlaceMention(_2); _3 = discriminant(_2); - switchInt(move _3) -> [0: bb4, otherwise: bb3]; + switchInt(move _3) -> [0: bb5, otherwise: bb3]; } bb2: { @@ -34,163 +34,179 @@ fn test_complex() -> () { } bb3: { - goto -> bb20; + goto -> bb22; } bb4: { - falseEdge -> [real: bb5, imaginary: bb3]; + goto -> bb2; } bb5: { - StorageLive(_4); - _4 = always_true() -> [return: bb6, unwind: bb33]; + falseEdge -> [real: bb7, imaginary: bb3]; } bb6: { - switchInt(move _4) -> [0: bb8, otherwise: bb7]; + goto -> bb3; } bb7: { + StorageLive(_4); + _4 = always_true() -> [return: bb8, unwind: bb37]; + } + + bb8: { + switchInt(move _4) -> [0: bb10, otherwise: bb9]; + } + + bb9: { StorageLive(_5); StorageLive(_6); StorageLive(_7); _7 = Droppy(const 0_u8); _6 = (_7.0: u8); _5 = Gt(move _6, const 0_u8); - switchInt(move _5) -> [0: bb10, otherwise: bb9]; + switchInt(move _5) -> [0: bb12, otherwise: bb11]; } - bb8: { - goto -> bb14; + bb10: { + goto -> bb16; } - bb9: { - drop(_7) -> [return: bb11, unwind: bb33]; + bb11: { + drop(_7) -> [return: bb13, unwind: bb37]; } - bb10: { - goto -> bb12; + bb12: { + goto -> bb14; } - bb11: { + bb13: { StorageDead(_7); StorageDead(_6); - goto -> bb17; + goto -> bb19; } - bb12: { - drop(_7) -> [return: bb13, unwind: bb33]; + bb14: { + drop(_7) -> [return: bb15, unwind: bb37]; } - bb13: { + bb15: { StorageDead(_7); StorageDead(_6); - goto -> bb14; + goto -> bb16; } - bb14: { + bb16: { StorageLive(_8); StorageLive(_9); StorageLive(_10); _10 = Droppy(const 1_u8); _9 = (_10.0: u8); _8 = Gt(move _9, const 1_u8); - switchInt(move _8) -> [0: bb16, otherwise: bb15]; + switchInt(move _8) -> [0: bb18, otherwise: bb17]; } - bb15: { - drop(_10) -> [return: bb17, unwind: bb33]; + bb17: { + drop(_10) -> [return: bb19, unwind: bb37]; } - bb16: { - goto -> bb18; + bb18: { + goto -> bb20; } - bb17: { + bb19: { StorageDead(_10); StorageDead(_9); _1 = const (); - goto -> bb21; + goto -> bb23; } - bb18: { - drop(_10) -> [return: bb19, unwind: bb33]; + bb20: { + drop(_10) -> [return: bb21, unwind: bb37]; } - bb19: { + bb21: { StorageDead(_10); StorageDead(_9); - goto -> bb20; + goto -> bb22; } - bb20: { + bb22: { _1 = const (); - goto -> bb21; + goto -> bb23; } - bb21: { + bb23: { StorageDead(_8); StorageDead(_5); StorageDead(_4); StorageDead(_2); StorageDead(_1); StorageLive(_11); - _11 = always_true() -> [return: bb22, unwind: bb33]; + _11 = always_true() -> [return: bb24, unwind: bb37]; } - bb22: { - switchInt(move _11) -> [0: bb24, otherwise: bb23]; + bb24: { + switchInt(move _11) -> [0: bb26, otherwise: bb25]; } - bb23: { - goto -> bb31; + bb25: { + goto -> bb35; } - bb24: { - goto -> bb25; + bb26: { + goto -> bb27; } - bb25: { + bb27: { StorageLive(_12); - _12 = E::f() -> [return: bb26, unwind: bb33]; + _12 = E::f() -> [return: bb28, unwind: bb37]; } - bb26: { + bb28: { PlaceMention(_12); _13 = discriminant(_12); - switchInt(move _13) -> [1: bb29, otherwise: bb28]; + switchInt(move _13) -> [1: bb32, otherwise: bb30]; } - bb27: { + bb29: { FakeRead(ForMatchedPlace(None), _12); unreachable; } - bb28: { - goto -> bb31; + bb30: { + goto -> bb35; } - bb29: { - falseEdge -> [real: bb30, imaginary: bb28]; + bb31: { + goto -> bb29; } - bb30: { + bb32: { + falseEdge -> [real: bb34, imaginary: bb30]; + } + + bb33: { + goto -> bb30; + } + + bb34: { _0 = const (); - goto -> bb32; + goto -> bb36; } - bb31: { + bb35: { _0 = const (); - goto -> bb32; + goto -> bb36; } - bb32: { + bb36: { StorageDead(_11); StorageDead(_12); return; } - bb33 (cleanup): { + bb37 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir index 88292dd05972e..4e91eb6f76fc4 100644 --- a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir +++ b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir @@ -28,7 +28,7 @@ fn full_tested_match() -> () { _2 = Option::::Some(const 42_i32); PlaceMention(_2); _3 = discriminant(_2); - switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; + switchInt(move _3) -> [0: bb2, 1: bb4, otherwise: bb1]; } bb1: { @@ -38,30 +38,38 @@ fn full_tested_match() -> () { bb2: { _1 = (const 3_i32, const 3_i32); - goto -> bb11; + goto -> bb13; } bb3: { - falseEdge -> [real: bb5, imaginary: bb4]; + goto -> bb1; } bb4: { - falseEdge -> [real: bb10, imaginary: bb2]; + falseEdge -> [real: bb7, imaginary: bb5]; } bb5: { + falseEdge -> [real: bb12, imaginary: bb2]; + } + + bb6: { + goto -> bb1; + } + + bb7: { StorageLive(_6); _6 = &((_2 as Some).0: i32); _4 = &fake _2; StorageLive(_7); - _7 = guard() -> [return: bb6, unwind: bb13]; + _7 = guard() -> [return: bb8, unwind: bb16]; } - bb6: { - switchInt(move _7) -> [0: bb8, otherwise: bb7]; + bb8: { + switchInt(move _7) -> [0: bb10, otherwise: bb9]; } - bb7: { + bb9: { StorageDead(_7); FakeRead(ForMatchGuard, _4); FakeRead(ForGuardBinding, _6); @@ -73,20 +81,20 @@ fn full_tested_match() -> () { StorageDead(_8); StorageDead(_5); StorageDead(_6); - goto -> bb11; + goto -> bb13; } - bb8: { - goto -> bb9; + bb10: { + goto -> bb11; } - bb9: { + bb11: { StorageDead(_7); StorageDead(_6); - goto -> bb4; + goto -> bb5; } - bb10: { + bb12: { StorageLive(_9); _9 = ((_2 as Some).0: i32); StorageLive(_10); @@ -94,10 +102,10 @@ fn full_tested_match() -> () { _1 = (const 2_i32, move _10); StorageDead(_10); StorageDead(_9); - goto -> bb11; + goto -> bb13; } - bb11: { + bb13: { PlaceMention(_1); StorageDead(_2); StorageDead(_1); @@ -105,12 +113,16 @@ fn full_tested_match() -> () { return; } - bb12: { + bb14: { FakeRead(ForMatchedPlace(None), _1); unreachable; } - bb13 (cleanup): { + bb15: { + goto -> bb14; + } + + bb16 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir index 205bb4980d904..0c67cc9f71e53 100644 --- a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir +++ b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir @@ -28,7 +28,7 @@ fn full_tested_match2() -> () { _2 = Option::::Some(const 42_i32); PlaceMention(_2); _3 = discriminant(_2); - switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; + switchInt(move _3) -> [0: bb2, 1: bb4, otherwise: bb1]; } bb1: { @@ -37,14 +37,18 @@ fn full_tested_match2() -> () { } bb2: { - falseEdge -> [real: bb10, imaginary: bb4]; + falseEdge -> [real: bb12, imaginary: bb5]; } bb3: { - falseEdge -> [real: bb5, imaginary: bb2]; + goto -> bb1; } bb4: { + falseEdge -> [real: bb7, imaginary: bb2]; + } + + bb5: { StorageLive(_9); _9 = ((_2 as Some).0: i32); StorageLive(_10); @@ -52,22 +56,26 @@ fn full_tested_match2() -> () { _1 = (const 2_i32, move _10); StorageDead(_10); StorageDead(_9); - goto -> bb11; + goto -> bb13; } - bb5: { + bb6: { + goto -> bb1; + } + + bb7: { StorageLive(_6); _6 = &((_2 as Some).0: i32); _4 = &fake _2; StorageLive(_7); - _7 = guard() -> [return: bb6, unwind: bb13]; + _7 = guard() -> [return: bb8, unwind: bb16]; } - bb6: { - switchInt(move _7) -> [0: bb8, otherwise: bb7]; + bb8: { + switchInt(move _7) -> [0: bb10, otherwise: bb9]; } - bb7: { + bb9: { StorageDead(_7); FakeRead(ForMatchGuard, _4); FakeRead(ForGuardBinding, _6); @@ -79,25 +87,25 @@ fn full_tested_match2() -> () { StorageDead(_8); StorageDead(_5); StorageDead(_6); - goto -> bb11; + goto -> bb13; } - bb8: { - goto -> bb9; + bb10: { + goto -> bb11; } - bb9: { + bb11: { StorageDead(_7); StorageDead(_6); - falseEdge -> [real: bb4, imaginary: bb2]; + falseEdge -> [real: bb5, imaginary: bb2]; } - bb10: { + bb12: { _1 = (const 3_i32, const 3_i32); - goto -> bb11; + goto -> bb13; } - bb11: { + bb13: { PlaceMention(_1); StorageDead(_2); StorageDead(_1); @@ -105,12 +113,16 @@ fn full_tested_match2() -> () { return; } - bb12: { + bb14: { FakeRead(ForMatchedPlace(None), _1); unreachable; } - bb13 (cleanup): { + bb15: { + goto -> bb14; + } + + bb16 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/match_false_edges.main.built.after.mir b/tests/mir-opt/building/match_false_edges.main.built.after.mir index 21f377a640452..b71b2412cdf47 100644 --- a/tests/mir-opt/building/match_false_edges.main.built.after.mir +++ b/tests/mir-opt/building/match_false_edges.main.built.after.mir @@ -39,7 +39,7 @@ fn main() -> () { _2 = Option::::Some(const 1_i32); PlaceMention(_2); _4 = discriminant(_2); - switchInt(move _4) -> [1: bb7, otherwise: bb2]; + switchInt(move _4) -> [1: bb8, otherwise: bb2]; } bb1: { @@ -48,12 +48,12 @@ fn main() -> () { } bb2: { - falseEdge -> [real: bb14, imaginary: bb5]; + falseEdge -> [real: bb15, imaginary: bb6]; } bb3: { _3 = discriminant(_2); - switchInt(move _3) -> [1: bb5, otherwise: bb4]; + switchInt(move _3) -> [1: bb6, otherwise: bb4]; } bb4: { @@ -61,38 +61,42 @@ fn main() -> () { _14 = _2; _1 = const 4_i32; StorageDead(_14); - goto -> bb20; + goto -> bb21; } bb5: { - falseEdge -> [real: bb15, imaginary: bb4]; + goto -> bb1; } bb6: { - goto -> bb4; + falseEdge -> [real: bb16, imaginary: bb4]; } bb7: { - falseEdge -> [real: bb9, imaginary: bb2]; + goto -> bb4; } bb8: { - goto -> bb2; + falseEdge -> [real: bb10, imaginary: bb2]; } bb9: { + goto -> bb2; + } + + bb10: { StorageLive(_7); _7 = &((_2 as Some).0: i32); _5 = &fake _2; StorageLive(_8); - _8 = guard() -> [return: bb10, unwind: bb22]; + _8 = guard() -> [return: bb11, unwind: bb24]; } - bb10: { - switchInt(move _8) -> [0: bb12, otherwise: bb11]; + bb11: { + switchInt(move _8) -> [0: bb13, otherwise: bb12]; } - bb11: { + bb12: { StorageDead(_8); FakeRead(ForMatchGuard, _5); FakeRead(ForGuardBinding, _7); @@ -101,42 +105,42 @@ fn main() -> () { _1 = const 1_i32; StorageDead(_6); StorageDead(_7); - goto -> bb20; + goto -> bb21; } - bb12: { - goto -> bb13; + bb13: { + goto -> bb14; } - bb13: { + bb14: { StorageDead(_8); StorageDead(_7); - falseEdge -> [real: bb8, imaginary: bb2]; + falseEdge -> [real: bb9, imaginary: bb2]; } - bb14: { + bb15: { StorageLive(_9); _9 = _2; _1 = const 2_i32; StorageDead(_9); - goto -> bb20; + goto -> bb21; } - bb15: { + bb16: { StorageLive(_11); _11 = &((_2 as Some).0: i32); _5 = &fake _2; StorageLive(_12); StorageLive(_13); _13 = (*_11); - _12 = guard2(move _13) -> [return: bb16, unwind: bb22]; + _12 = guard2(move _13) -> [return: bb17, unwind: bb24]; } - bb16: { - switchInt(move _12) -> [0: bb18, otherwise: bb17]; + bb17: { + switchInt(move _12) -> [0: bb19, otherwise: bb18]; } - bb17: { + bb18: { StorageDead(_13); StorageDead(_12); FakeRead(ForMatchGuard, _5); @@ -146,21 +150,21 @@ fn main() -> () { _1 = const 3_i32; StorageDead(_10); StorageDead(_11); - goto -> bb20; + goto -> bb21; } - bb18: { - goto -> bb19; + bb19: { + goto -> bb20; } - bb19: { + bb20: { StorageDead(_13); StorageDead(_12); StorageDead(_11); - falseEdge -> [real: bb6, imaginary: bb4]; + falseEdge -> [real: bb7, imaginary: bb4]; } - bb20: { + bb21: { PlaceMention(_1); StorageDead(_2); StorageDead(_1); @@ -168,12 +172,16 @@ fn main() -> () { return; } - bb21: { + bb22: { FakeRead(ForMatchedPlace(None), _1); unreachable; } - bb22 (cleanup): { + bb23: { + goto -> bb22; + } + + bb24 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/simple_match.match_bool.built.after.mir b/tests/mir-opt/building/simple_match.match_bool.built.after.mir index cd51c942bee08..faa2456fd1007 100644 --- a/tests/mir-opt/building/simple_match.match_bool.built.after.mir +++ b/tests/mir-opt/building/simple_match.match_bool.built.after.mir @@ -6,7 +6,7 @@ fn match_bool(_1: bool) -> usize { bb0: { PlaceMention(_1); - switchInt(_1) -> [0: bb2, otherwise: bb3]; + switchInt(_1) -> [0: bb2, otherwise: bb4]; } bb1: { @@ -16,19 +16,27 @@ fn match_bool(_1: bool) -> usize { bb2: { _0 = const 20_usize; - goto -> bb5; + goto -> bb7; } bb3: { - falseEdge -> [real: bb4, imaginary: bb2]; + goto -> bb1; } bb4: { - _0 = const 10_usize; - goto -> bb5; + falseEdge -> [real: bb6, imaginary: bb2]; } bb5: { + goto -> bb2; + } + + bb6: { + _0 = const 10_usize; + goto -> bb7; + } + + bb7: { return; } } diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir index 282c9704ffca7..128af9c56024d 100644 --- a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir @@ -30,7 +30,7 @@ fn move_out_by_subslice() -> () { StorageLive(_2); _3 = SizeOf(i32); _4 = AlignOf(i32); - _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb13]; + _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb14]; } bb1: { @@ -38,7 +38,7 @@ fn move_out_by_subslice() -> () { _6 = ShallowInitBox(move _5, i32); (*_6) = const 1_i32; _2 = move _6; - drop(_6) -> [return: bb2, unwind: bb12]; + drop(_6) -> [return: bb2, unwind: bb13]; } bb2: { @@ -46,7 +46,7 @@ fn move_out_by_subslice() -> () { StorageLive(_7); _8 = SizeOf(i32); _9 = AlignOf(i32); - _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb12]; + _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb13]; } bb3: { @@ -54,18 +54,18 @@ fn move_out_by_subslice() -> () { _11 = ShallowInitBox(move _10, i32); (*_11) = const 2_i32; _7 = move _11; - drop(_11) -> [return: bb4, unwind: bb11]; + drop(_11) -> [return: bb4, unwind: bb12]; } bb4: { StorageDead(_11); _1 = [move _2, move _7]; - drop(_7) -> [return: bb5, unwind: bb12]; + drop(_7) -> [return: bb5, unwind: bb13]; } bb5: { StorageDead(_7); - drop(_2) -> [return: bb6, unwind: bb13]; + drop(_2) -> [return: bb6, unwind: bb14]; } bb6: { @@ -75,7 +75,7 @@ fn move_out_by_subslice() -> () { StorageLive(_12); _12 = move _1[0..2]; _0 = const (); - drop(_12) -> [return: bb8, unwind: bb10]; + drop(_12) -> [return: bb9, unwind: bb11]; } bb7: { @@ -84,28 +84,32 @@ fn move_out_by_subslice() -> () { } bb8: { - StorageDead(_12); - drop(_1) -> [return: bb9, unwind: bb13]; + goto -> bb7; } bb9: { - StorageDead(_1); - return; + StorageDead(_12); + drop(_1) -> [return: bb10, unwind: bb14]; } - bb10 (cleanup): { - drop(_1) -> [return: bb13, unwind terminate(cleanup)]; + bb10: { + StorageDead(_1); + return; } bb11 (cleanup): { - drop(_7) -> [return: bb12, unwind terminate(cleanup)]; + drop(_1) -> [return: bb14, unwind terminate(cleanup)]; } bb12 (cleanup): { - drop(_2) -> [return: bb13, unwind terminate(cleanup)]; + drop(_7) -> [return: bb13, unwind terminate(cleanup)]; } bb13 (cleanup): { + drop(_2) -> [return: bb14, unwind terminate(cleanup)]; + } + + bb14 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir index d1956c91b88c0..d50a6872a4170 100644 --- a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir @@ -30,7 +30,7 @@ fn move_out_from_end() -> () { StorageLive(_2); _3 = SizeOf(i32); _4 = AlignOf(i32); - _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb13]; + _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb14]; } bb1: { @@ -38,7 +38,7 @@ fn move_out_from_end() -> () { _6 = ShallowInitBox(move _5, i32); (*_6) = const 1_i32; _2 = move _6; - drop(_6) -> [return: bb2, unwind: bb12]; + drop(_6) -> [return: bb2, unwind: bb13]; } bb2: { @@ -46,7 +46,7 @@ fn move_out_from_end() -> () { StorageLive(_7); _8 = SizeOf(i32); _9 = AlignOf(i32); - _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb12]; + _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb13]; } bb3: { @@ -54,18 +54,18 @@ fn move_out_from_end() -> () { _11 = ShallowInitBox(move _10, i32); (*_11) = const 2_i32; _7 = move _11; - drop(_11) -> [return: bb4, unwind: bb11]; + drop(_11) -> [return: bb4, unwind: bb12]; } bb4: { StorageDead(_11); _1 = [move _2, move _7]; - drop(_7) -> [return: bb5, unwind: bb12]; + drop(_7) -> [return: bb5, unwind: bb13]; } bb5: { StorageDead(_7); - drop(_2) -> [return: bb6, unwind: bb13]; + drop(_2) -> [return: bb6, unwind: bb14]; } bb6: { @@ -75,7 +75,7 @@ fn move_out_from_end() -> () { StorageLive(_12); _12 = move _1[1 of 2]; _0 = const (); - drop(_12) -> [return: bb8, unwind: bb10]; + drop(_12) -> [return: bb9, unwind: bb11]; } bb7: { @@ -84,28 +84,32 @@ fn move_out_from_end() -> () { } bb8: { - StorageDead(_12); - drop(_1) -> [return: bb9, unwind: bb13]; + goto -> bb7; } bb9: { - StorageDead(_1); - return; + StorageDead(_12); + drop(_1) -> [return: bb10, unwind: bb14]; } - bb10 (cleanup): { - drop(_1) -> [return: bb13, unwind terminate(cleanup)]; + bb10: { + StorageDead(_1); + return; } bb11 (cleanup): { - drop(_7) -> [return: bb12, unwind terminate(cleanup)]; + drop(_1) -> [return: bb14, unwind terminate(cleanup)]; } bb12 (cleanup): { - drop(_2) -> [return: bb13, unwind terminate(cleanup)]; + drop(_7) -> [return: bb13, unwind terminate(cleanup)]; } bb13 (cleanup): { + drop(_2) -> [return: bb14, unwind terminate(cleanup)]; + } + + bb14 (cleanup): { resume; } } diff --git a/tests/mir-opt/issue_72181.bar.built.after.mir b/tests/mir-opt/issue_72181.bar.built.after.mir index b6cc7d2219569..3ab9152f8bb6b 100644 --- a/tests/mir-opt/issue_72181.bar.built.after.mir +++ b/tests/mir-opt/issue_72181.bar.built.after.mir @@ -19,4 +19,8 @@ fn bar(_1: [(Never, u32); 1]) -> u32 { FakeRead(ForMatchedPlace(None), _1); unreachable; } + + bb2: { + goto -> bb1; + } } diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir index 12c4a2b63253d..cff20702bf7ca 100644 --- a/tests/mir-opt/issue_72181.main.built.after.mir +++ b/tests/mir-opt/issue_72181.main.built.after.mir @@ -22,7 +22,7 @@ fn main() -> () { bb0: { StorageLive(_1); - _1 = std::mem::size_of::() -> [return: bb1, unwind: bb5]; + _1 = std::mem::size_of::() -> [return: bb1, unwind: bb7]; } bb1: { @@ -42,7 +42,7 @@ fn main() -> () { _6 = const 0_usize; _7 = Len(_2); _8 = Lt(_6, _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb3, unwind: bb5]; + assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb4, unwind: bb7]; } bb2: { @@ -51,6 +51,10 @@ fn main() -> () { } bb3: { + goto -> bb2; + } + + bb4: { _5 = (_2[_6].0: u64); PlaceMention(_5); StorageDead(_6); @@ -60,12 +64,16 @@ fn main() -> () { return; } - bb4: { + bb5: { FakeRead(ForMatchedPlace(None), _5); unreachable; } - bb5 (cleanup): { + bb6: { + goto -> bb5; + } + + bb7 (cleanup): { resume; } } diff --git a/tests/mir-opt/issue_91633.bar.built.after.mir b/tests/mir-opt/issue_91633.bar.built.after.mir index 53829588a1b36..3dcdcab9dea3d 100644 --- a/tests/mir-opt/issue_91633.bar.built.after.mir +++ b/tests/mir-opt/issue_91633.bar.built.after.mir @@ -12,7 +12,7 @@ fn bar(_1: Box<[T]>) -> () { StorageLive(_2); StorageLive(_3); _3 = &(*_1); - _2 = <[T] as Index>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb4]; + _2 = <[T] as Index>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb5]; } bb1: { @@ -20,7 +20,7 @@ fn bar(_1: Box<[T]>) -> () { PlaceMention((*_2)); StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb3, unwind: bb5]; + drop(_1) -> [return: bb4, unwind: bb6]; } bb2: { @@ -29,14 +29,18 @@ fn bar(_1: Box<[T]>) -> () { } bb3: { - return; + goto -> bb2; } - bb4 (cleanup): { - drop(_1) -> [return: bb5, unwind terminate(cleanup)]; + bb4: { + return; } bb5 (cleanup): { + drop(_1) -> [return: bb6, unwind terminate(cleanup)]; + } + + bb6 (cleanup): { resume; } } diff --git a/tests/mir-opt/issue_91633.hey.built.after.mir b/tests/mir-opt/issue_91633.hey.built.after.mir index a537e509996d7..e782f4d1a23fa 100644 --- a/tests/mir-opt/issue_91633.hey.built.after.mir +++ b/tests/mir-opt/issue_91633.hey.built.after.mir @@ -14,7 +14,7 @@ fn hey(_1: &[T]) -> () { StorageLive(_3); StorageLive(_4); _4 = &(*_1); - _3 = <[T] as Index>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb3]; + _3 = <[T] as Index>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb4]; } bb1: { @@ -32,7 +32,11 @@ fn hey(_1: &[T]) -> () { unreachable; } - bb3 (cleanup): { + bb3: { + goto -> bb2; + } + + bb4 (cleanup): { resume; } } diff --git a/tests/mir-opt/issue_99325.main.built.after.32bit.mir b/tests/mir-opt/issue_99325.main.built.after.32bit.mir index 53254f76dbcb9..f8e195466ee1b 100644 --- a/tests/mir-opt/issue_99325.main.built.after.32bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.32bit.mir @@ -67,7 +67,7 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb23]; + _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb25]; } bb1: { @@ -91,7 +91,7 @@ fn main() -> () { _11 = &(*_8); StorageLive(_12); _12 = &(*_9); - _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb3, unwind: bb23]; + _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb4, unwind: bb25]; } bb2: { @@ -100,20 +100,24 @@ fn main() -> () { } bb3: { - switchInt(move _10) -> [0: bb5, otherwise: bb4]; + goto -> bb2; } bb4: { - StorageDead(_12); - StorageDead(_11); - goto -> bb9; + switchInt(move _10) -> [0: bb6, otherwise: bb5]; } bb5: { - goto -> bb6; + StorageDead(_12); + StorageDead(_11); + goto -> bb10; } bb6: { + goto -> bb7; + } + + bb7: { StorageDead(_12); StorageDead(_11); StorageLive(_14); @@ -132,10 +136,10 @@ fn main() -> () { _19 = &(*_20); StorageLive(_21); _21 = Option::>::None; - _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb23; + _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb25; } - bb7: { + bb8: { StorageDead(_21); StorageDead(_19); StorageDead(_17); @@ -147,23 +151,23 @@ fn main() -> () { unreachable; } - bb8: { - goto -> bb10; + bb9: { + goto -> bb11; } - bb9: { + bb10: { _1 = const (); - goto -> bb10; + goto -> bb11; } - bb10: { + bb11: { StorageDead(_10); StorageDead(_9); StorageDead(_8); - goto -> bb11; + goto -> bb12; } - bb11: { + bb12: { StorageDead(_7); StorageDead(_6); StorageDead(_4); @@ -173,10 +177,10 @@ fn main() -> () { StorageLive(_23); StorageLive(_24); StorageLive(_25); - _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23]; + _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb13, unwind: bb25]; } - bb12: { + bb13: { _24 = &_25; StorageLive(_26); StorageLive(_27); @@ -195,29 +199,33 @@ fn main() -> () { _31 = &(*_28); StorageLive(_32); _32 = &(*_29); - _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb23]; + _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb16, unwind: bb25]; } - bb13: { + bb14: { FakeRead(ForMatchedPlace(None), _23); unreachable; } - bb14: { - switchInt(move _30) -> [0: bb16, otherwise: bb15]; + bb15: { + goto -> bb14; } - bb15: { + bb16: { + switchInt(move _30) -> [0: bb18, otherwise: bb17]; + } + + bb17: { StorageDead(_32); StorageDead(_31); - goto -> bb20; + goto -> bb22; } - bb16: { - goto -> bb17; + bb18: { + goto -> bb19; } - bb17: { + bb19: { StorageDead(_32); StorageDead(_31); StorageLive(_34); @@ -236,10 +244,10 @@ fn main() -> () { _39 = &(*_40); StorageLive(_41); _41 = Option::>::None; - _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb23; + _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb25; } - bb18: { + bb20: { StorageDead(_41); StorageDead(_39); StorageDead(_37); @@ -251,23 +259,23 @@ fn main() -> () { unreachable; } - bb19: { - goto -> bb21; + bb21: { + goto -> bb23; } - bb20: { + bb22: { _22 = const (); - goto -> bb21; + goto -> bb23; } - bb21: { + bb23: { StorageDead(_30); StorageDead(_29); StorageDead(_28); - goto -> bb22; + goto -> bb24; } - bb22: { + bb24: { StorageDead(_27); StorageDead(_25); StorageDead(_23); @@ -276,7 +284,7 @@ fn main() -> () { return; } - bb23 (cleanup): { + bb25 (cleanup): { resume; } } diff --git a/tests/mir-opt/issue_99325.main.built.after.64bit.mir b/tests/mir-opt/issue_99325.main.built.after.64bit.mir index 53254f76dbcb9..f8e195466ee1b 100644 --- a/tests/mir-opt/issue_99325.main.built.after.64bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.64bit.mir @@ -67,7 +67,7 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb23]; + _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb25]; } bb1: { @@ -91,7 +91,7 @@ fn main() -> () { _11 = &(*_8); StorageLive(_12); _12 = &(*_9); - _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb3, unwind: bb23]; + _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb4, unwind: bb25]; } bb2: { @@ -100,20 +100,24 @@ fn main() -> () { } bb3: { - switchInt(move _10) -> [0: bb5, otherwise: bb4]; + goto -> bb2; } bb4: { - StorageDead(_12); - StorageDead(_11); - goto -> bb9; + switchInt(move _10) -> [0: bb6, otherwise: bb5]; } bb5: { - goto -> bb6; + StorageDead(_12); + StorageDead(_11); + goto -> bb10; } bb6: { + goto -> bb7; + } + + bb7: { StorageDead(_12); StorageDead(_11); StorageLive(_14); @@ -132,10 +136,10 @@ fn main() -> () { _19 = &(*_20); StorageLive(_21); _21 = Option::>::None; - _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb23; + _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb25; } - bb7: { + bb8: { StorageDead(_21); StorageDead(_19); StorageDead(_17); @@ -147,23 +151,23 @@ fn main() -> () { unreachable; } - bb8: { - goto -> bb10; + bb9: { + goto -> bb11; } - bb9: { + bb10: { _1 = const (); - goto -> bb10; + goto -> bb11; } - bb10: { + bb11: { StorageDead(_10); StorageDead(_9); StorageDead(_8); - goto -> bb11; + goto -> bb12; } - bb11: { + bb12: { StorageDead(_7); StorageDead(_6); StorageDead(_4); @@ -173,10 +177,10 @@ fn main() -> () { StorageLive(_23); StorageLive(_24); StorageLive(_25); - _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23]; + _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb13, unwind: bb25]; } - bb12: { + bb13: { _24 = &_25; StorageLive(_26); StorageLive(_27); @@ -195,29 +199,33 @@ fn main() -> () { _31 = &(*_28); StorageLive(_32); _32 = &(*_29); - _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb23]; + _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb16, unwind: bb25]; } - bb13: { + bb14: { FakeRead(ForMatchedPlace(None), _23); unreachable; } - bb14: { - switchInt(move _30) -> [0: bb16, otherwise: bb15]; + bb15: { + goto -> bb14; } - bb15: { + bb16: { + switchInt(move _30) -> [0: bb18, otherwise: bb17]; + } + + bb17: { StorageDead(_32); StorageDead(_31); - goto -> bb20; + goto -> bb22; } - bb16: { - goto -> bb17; + bb18: { + goto -> bb19; } - bb17: { + bb19: { StorageDead(_32); StorageDead(_31); StorageLive(_34); @@ -236,10 +244,10 @@ fn main() -> () { _39 = &(*_40); StorageLive(_41); _41 = Option::>::None; - _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb23; + _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb25; } - bb18: { + bb20: { StorageDead(_41); StorageDead(_39); StorageDead(_37); @@ -251,23 +259,23 @@ fn main() -> () { unreachable; } - bb19: { - goto -> bb21; + bb21: { + goto -> bb23; } - bb20: { + bb22: { _22 = const (); - goto -> bb21; + goto -> bb23; } - bb21: { + bb23: { StorageDead(_30); StorageDead(_29); StorageDead(_28); - goto -> bb22; + goto -> bb24; } - bb22: { + bb24: { StorageDead(_27); StorageDead(_25); StorageDead(_23); @@ -276,7 +284,7 @@ fn main() -> () { return; } - bb23 (cleanup): { + bb25 (cleanup): { resume; } }