diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index d831d8ba2c4..b65d859e7d7 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -56,7 +56,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // create binding start block for link them by false edges let candidate_count = arms.iter().fold(0, |ac, c| ac + c.patterns.len()); - let binding_start_blocks: Vec<_> = (0..candidate_count + 1) + let pre_binding_blocks: Vec<_> = (0..candidate_count + 1) .map(|_| self.cfg.start_new_block()).collect(); // assemble a list of candidates: there is one candidate per @@ -72,23 +72,23 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { arm.patterns.iter() .map(move |pat| (arm_index, pat, arm.guard.clone())) }) - .zip(binding_start_blocks.iter().zip(binding_start_blocks.iter().skip(1))) + .zip(pre_binding_blocks.iter().zip(pre_binding_blocks.iter().skip(1))) .map(|((arm_index, pattern, guard), - (binding_start_block, next_candidate_binding_start_block))| { + (pre_binding_block, next_candidate_pre_binding_block))| { Candidate { span: pattern.span, match_pairs: vec![MatchPair::new(discriminant_lvalue.clone(), pattern)], bindings: vec![], guard, arm_index, - binding_start_block: *binding_start_block, - next_candidate_binding_start_block: *next_candidate_binding_start_block, + pre_binding_block: *pre_binding_block, + next_candidate_pre_binding_block: *next_candidate_pre_binding_block, } }) .collect(); let outer_source_info = self.source_info(span); - self.cfg.terminate(*binding_start_blocks.last().unwrap(), + self.cfg.terminate(*pre_binding_blocks.last().unwrap(), outer_source_info, TerminatorKind::Unreachable); // this will generate code to test discriminant_lvalue and @@ -165,8 +165,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // since we don't call `match_candidates`, next fields is unused arm_index: 0, - binding_start_block: block, - next_candidate_binding_start_block: block + pre_binding_block: block, + next_candidate_pre_binding_block: block }; // Simplify the candidate. Since the pattern is irrefutable, this should @@ -298,8 +298,8 @@ pub struct Candidate<'pat, 'tcx:'pat> { arm_index: usize, // ...and the blocks for add false edges between candidates - binding_start_block: BasicBlock, - next_candidate_binding_start_block: BasicBlock, + pre_binding_block: BasicBlock, + next_candidate_pre_binding_block: BasicBlock, } #[derive(Clone, Debug)] @@ -723,12 +723,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let candidate_source_info = self.source_info(candidate.span); self.cfg.terminate(block, candidate_source_info, - TerminatorKind::FalseEdges { - real_target: candidate.binding_start_block, - imaginary_targets: - vec![candidate.next_candidate_binding_start_block]}); + TerminatorKind::Goto { target: candidate.pre_binding_block }); + + block = self.cfg.start_new_block(); + self.cfg.terminate(candidate.pre_binding_block, candidate_source_info, + TerminatorKind::FalseEdges { + real_target: block, + imaginary_targets: + vec![candidate.next_candidate_pre_binding_block]}); - block = candidate.binding_start_block; self.bind_matched_candidate(block, candidate.bindings); if let Some(guard) = candidate.guard { @@ -748,7 +751,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { TerminatorKind::FalseEdges { real_target: otherwise, imaginary_targets: - vec![candidate.next_candidate_binding_start_block] }); + vec![candidate.next_candidate_pre_binding_block] }); Some(otherwise) } else { self.cfg.terminate(block, candidate_source_info, diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index cf3c9fefa47..4792bf2b213 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -598,8 +598,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { bindings: candidate.bindings.clone(), guard: candidate.guard.clone(), arm_index: candidate.arm_index, - binding_start_block: candidate.binding_start_block, - next_candidate_binding_start_block: candidate.next_candidate_binding_start_block, + pre_binding_block: candidate.pre_binding_block, + next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block, } } @@ -661,8 +661,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { bindings: candidate.bindings.clone(), guard: candidate.guard.clone(), arm_index: candidate.arm_index, - binding_start_block: candidate.binding_start_block, - next_candidate_binding_start_block: candidate.next_candidate_binding_start_block, + pre_binding_block: candidate.pre_binding_block, + next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block, } } diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs index 38e76b001da..53e5deeb9bd 100644 --- a/src/test/mir-opt/match_false_edges.rs +++ b/src/test/mir-opt/match_false_edges.rs @@ -43,7 +43,7 @@ fn main() { // ... // _2 = std::option::Option::Some(const 42i32,); // _5 = discriminant(_2); -// switchInt(_5) -> [0isize: bb6, otherwise: bb7]; +// switchInt(_5) -> [0isize: bb5, otherwise: bb3]; // } // bb1: { // arm1 // StorageLive(_7); @@ -52,13 +52,35 @@ fn main() { // ... // goto -> bb11; // } -// bb2: { // binding1 guard +// bb2: { // binding3(empty) and arm3 +// _1 = const 3i32; +// goto -> bb11; +// } +// bb3: { +// falseEdges -> [real: bb7, imaginary: bb4]; //pre_binding1 +// } +// bb4: { +// falseEdges -> [real: bb10, imaginary: bb5]; //pre_binding2 +// } +// bb5: { +// falseEdges -> [real: bb2, imaginary: bb6]; //pre_binding3 +// } +// bb6: { +// unreachable; +// } +// bb7: { // binding1 and guard // StorageLive(_3); // _3 = ((_2 as Some).0: i32); // StorageLive(_6); // _6 = const guard() -> bb8; // } -// bb3: { // binding2 & arm2 +// bb8: { // end of guard +// switchInt(_6) -> [0u8: bb9, otherwise: bb1]; +// } +// bb9: { // to pre_binding2 +// falseEdges -> [real: bb4, imaginary: bb4]; +// } +// bb10: { // binding2 and arm2 // StorageLive(_4); // _4 = ((_2 as Some).0: i32); // StorageLive(_8); @@ -67,28 +89,6 @@ fn main() { // StorageDead(_8); // goto -> bb11; // } -// bb4: { // binding3(empty) arm3 -// _1 = const 3i32; -// goto -> bb11; -// } -// bb5: { -// unreachable; -// } -// bb6: { -// falseEdges -> [real: bb4, imaginary: bb5]; // from before_binding3 to unreachable -// } -// bb7: { -// falseEdges -> [real: bb2, imaginary: bb3]; // from before_binding1 to binding2 -// } -// bb8: { -// switchInt(_6) -> [0u8: bb9, otherwise: bb1]; // end of guard -// } -// bb9: { -// falseEdges -> [real: bb10, imaginary: bb3]; // after_guard to binding2 -// } -// bb10: { -// falseEdges -> [real: bb3, imaginary: bb4]; // from before_binding2 to binding3 -// } // bb11: { // ... // return; @@ -102,68 +102,72 @@ fn main() { // ... // _2 = std::option::Option::Some(const 1i32,); // _7 = discriminant(_2); -// switchInt(_7) -> [1isize: bb8, otherwise: bb11]; +// switchInt(_7) -> [1isize: bb3, otherwise: bb4]; // } // bb1: { // arm1 // _1 = const 1i32; -// goto -> bb15; +// goto -> bb16; // } // bb2: { // arm3 // _1 = const 3i32; -// goto -> bb15; +// goto -> bb16; // } -// bb3: { // binding1: Some(w) if guard() => -// StorageLive(_3); -// _3 = ((_2 as Some).0: i32); -// StorageLive(_8); -// _8 = const guard() -> bb9; -// } -// bb4: { // binding2 & arm2 -// StorageLive(_4); -// _4 = _2; -// _1 = const 2i32; -// goto -> bb15; -// } -// bb5: { // binding3: Some(y) if guard2(y) => -// StorageLive(_5); -// _5 = ((_2 as Some).0: i32); -// StorageLive(_10); -// StorageLive(_11); -// _11 = _5; -// _10 = const guard2(_11) -> bb12; -// } -// bb6: { // binding4 & arm4 -// StorageLive(_6); -// _6 = _2; -// _1 = const 4i32; -// goto -> bb15; -// } -// bb7: { -// unreachable; -// } -// bb8: { -// falseEdges -> [real: bb3, imaginary: bb4]; // from before_binding1 to binding2 -// } -// bb9: { -// switchInt(_8) -> [0u8: bb10, otherwise: bb1]; // end of gurard -// } -// bb10: { -// falseEdges -> [real: bb11, imaginary: bb4]; // after guard to binding2 -// } -// bb11: { -// falseEdges -> [real: bb4, imaginary: bb5]; // from before_binding2 to binding3 -// } -// bb12: { +// +// bb3: { +// falseEdges -> [real: bb8, imaginary: bb4]; //pre_binding1 +// } +// bb4: { +// falseEdges -> [real: bb11, imaginary: bb5]; //pre_binding2 +// } +// bb5: { +// falseEdges -> [real: bb12, imaginary: bb6]; //pre_binding3 +// } +// bb6: { +// falseEdges -> [real: bb15, imaginary: bb7]; //pre_binding4 +// } +// bb7: { +// unreachable; +// } +// bb8: { // binding1: Some(w) if guard() +// StorageLive(_3); +// _3 = ((_2 as Some).0: i32); +// StorageLive(_8); +// _8 = const guard() -> bb9; +// } +// bb9: { //end of guard +// switchInt(_8) -> [0u8: bb10, otherwise: bb1]; +// } +// bb10: { // to pre_binding2 +// falseEdges -> [real: bb4, imaginary: bb4]; +// } +// bb11: { // binding2 & arm2 +// StorageLive(_4); +// _4 = _2; +// _1 = const 2i32; +// goto -> bb16; +// } +// bb12: { // binding3: Some(y) if guard2(y) +// StorageLive(_5); +// _5 = ((_2 as Some).0: i32); +// StorageLive(_10); +// StorageLive(_11); +// _11 = _5; +// _10 = const guard2(_11) -> bb13; +// } +// bb13: { // end of guard2 // StorageDead(_11); -// switchInt(_10) -> [0u8: bb13, otherwise: bb2]; // end of guard2 -// } -// bb13: { -// falseEdges -> [real: bb14, imaginary: bb6]; // after guard2 to binding4 -// } -// bb14: { -// falseEdges -> [real: bb6, imaginary: bb7]; // from befor binding4 to unreachable -// } -// bb15: { +// switchInt(_10) -> [0u8: bb14, otherwise: bb2]; +// } +// bb14: { // to pre_binding4 +// falseEdges -> [real: bb6, imaginary: bb6]; +// } +// bb15: { // binding4 & arm4 +// StorageLive(_6); +// _6 = _2; +// _1 = const 4i32; +// goto -> bb16; +// } +// bb16: { // ... // return; // }