about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/transform/match_branches.rs16
-rw-r--r--src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff64
2 files changed, 75 insertions, 5 deletions
diff --git a/src/librustc_mir/transform/match_branches.rs b/src/librustc_mir/transform/match_branches.rs
index 07dec23429b..74da6d5e629 100644
--- a/src/librustc_mir/transform/match_branches.rs
+++ b/src/librustc_mir/transform/match_branches.rs
@@ -52,8 +52,11 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
                         if let Some(f_c) = f_c.literal.try_eval_bool(tcx, param_env) {
                             // This should also be a bool because it's writing to the same place
                             let s_c = s_c.literal.try_eval_bool(tcx, param_env).unwrap();
-                            assert_ne!(f_c, s_c, "Unexpected match would've compared eq earlier");
-                            continue;
+                            if f_c != s_c {
+                                // have to check this here because f_c & s_c might have
+                                // different spans.
+                                continue;
+                            }
                         }
                         continue 'outer;
                     }
@@ -63,9 +66,9 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
             }
             // Take owenership of items now that we know we can optimize.
             let discr = discr.clone();
+            let (from, first) = bbs.pick2_mut(bb_idx, first);
 
-            bbs[bb_idx].terminator_mut().kind = TerminatorKind::Goto { target: first };
-            for s in bbs[first].statements.iter_mut() {
+            let new_stmts = first.statements.iter().cloned().map(|mut s| {
                 if let StatementKind::Assign(box (_, ref mut rhs)) = s.kind {
                     if let Rvalue::Use(Operand::Constant(c)) = rhs {
                         let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size;
@@ -81,7 +84,10 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
                         }
                     }
                 }
-            }
+                s
+            });
+            from.statements.extend(new_stmts);
+            from.terminator_mut().kind = first.terminator().kind.clone();
         }
     }
 }
diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..b0a861f6c5e
--- /dev/null
+++ b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff
@@ -0,0 +1,64 @@
+- // MIR for `foo` before MatchBranchSimplification
++ // MIR for `foo` after MatchBranchSimplification
+  
+  fn foo(_1: std::option::Option<()>) -> () {
+      debug bar => _1;                     // in scope 0 at $DIR/matches_reduce_branches.rs:3:8: 3:11
+      let mut _0: ();                      // return place in scope 0 at $DIR/matches_reduce_branches.rs:3:25: 3:25
+      let mut _2: bool;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _3: isize;                   // in scope 0 at $DIR/matches_reduce_branches.rs:4:22: 4:26
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _3 = discriminant(_1);           // scope 0 at $DIR/matches_reduce_branches.rs:4:22: 4:26
+-         switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:4:22: 4:26
++         goto -> bb2;                     // scope 0 at $DIR/matches_reduce_branches.rs:4:22: 4:26
+      }
+  
+      bb1: {
+          _2 = const false;                // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                                           // ty::Const
+                                           // + ty: bool
+                                           // + val: Value(Scalar(0x00))
+                                           // mir::Constant
+                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                                           // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
+          goto -> bb3;                     // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      }
+  
+      bb2: {
+-         _2 = const true;                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
++         _2 = Eq(move _3, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+                                           // ty::Const
+-                                          // + ty: bool
+-                                          // + val: Value(Scalar(0x01))
++                                          // + ty: isize
++                                          // + val: Value(Scalar(0x0000000000000000))
+                                           // mir::Constant
+-                                          // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+-                                          // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
++                                          // + span: $DIR/matches_reduce_branches.rs:1:1: 1:1
++                                          // + literal: Const { ty: isize, val: Value(Scalar(0x0000000000000000)) }
+          goto -> bb3;                     // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      }
+  
+      bb3: {
+          switchInt(_2) -> [false: bb4, otherwise: bb5]; // scope 0 at $DIR/matches_reduce_branches.rs:4:5: 6:6
+      }
+  
+      bb4: {
+          _0 = const ();                   // scope 0 at $DIR/matches_reduce_branches.rs:4:5: 6:6
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/matches_reduce_branches.rs:4:5: 6:6
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+          goto -> bb5;                     // scope 0 at $DIR/matches_reduce_branches.rs:4:5: 6:6
+      }
+  
+      bb5: {
+          StorageDead(_2);                 // scope 0 at $DIR/matches_reduce_branches.rs:7:1: 7:2
+          return;                          // scope 0 at $DIR/matches_reduce_branches.rs:7:2: 7:2
+      }
+  }
+