about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkadmin <julianknodt@gmail.com>2020-08-14 00:11:36 +0000
committerkadmin <julianknodt@gmail.com>2020-08-14 01:03:16 +0000
commitfd740266de93f89195eee78a0feaa770bf90a47e (patch)
treef4204b2b82cb5298d890a01940ae4ace15d92998
parentc0a811a24ee926431f6e8fea6984430138a5fee0 (diff)
downloadrust-fd740266de93f89195eee78a0feaa770bf90a47e.tar.gz
rust-fd740266de93f89195eee78a0feaa770bf90a47e.zip
Add fix
This also explicitly checks that the types are `bool`. `try_eval_bool` also appears to just
succeed for `u8`, so this ensures that it actually is a bool before casting.
-rw-r--r--src/librustc_mir/transform/match_branches.rs16
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff.32bit40
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff.64bit40
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff.32bit40
-rw-r--r--src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff.64bit40
-rw-r--r--src/test/mir-opt/matches_u8.rs13
6 files changed, 179 insertions, 10 deletions
diff --git a/src/librustc_mir/transform/match_branches.rs b/src/librustc_mir/transform/match_branches.rs
index 74da6d5e629..67021ae512b 100644
--- a/src/librustc_mir/transform/match_branches.rs
+++ b/src/librustc_mir/transform/match_branches.rs
@@ -48,15 +48,13 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
                     (
                         StatementKind::Assign(box (lhs_f, Rvalue::Use(Operand::Constant(f_c)))),
                         StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(s_c)))),
-                    ) if lhs_f == lhs_s => {
-                        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();
-                            if f_c != s_c {
-                                // have to check this here because f_c & s_c might have
-                                // different spans.
-                                continue;
-                            }
+                    ) if lhs_f == lhs_s && f_c.literal.ty.is_bool() && s_c.literal.ty.is_bool() => {
+                        let f_c = f_c.literal.try_eval_bool(tcx, param_env).unwrap();
+                        let s_c = s_c.literal.try_eval_bool(tcx, param_env).unwrap();
+                        if f_c != s_c {
+                            // have to check this here because f_c & s_c might have
+                            // different spans.
+                            continue;
                         }
                         continue 'outer;
                     }
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff.32bit b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff.32bit
new file mode 100644
index 00000000000..c41bd999dc9
--- /dev/null
+++ b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff.32bit
@@ -0,0 +1,40 @@
+- // MIR for `exhaustive_match` before MatchBranchSimplification
++ // MIR for `exhaustive_match` after MatchBranchSimplification
+  
+  fn exhaustive_match(_1: E) -> u8 {
+      debug e => _1;                       // in scope 0 at $DIR/matches_u8.rs:11:25: 11:26
+      let mut _0: u8;                      // return place in scope 0 at $DIR/matches_u8.rs:11:34: 11:36
+      let mut _2: isize;                   // in scope 0 at $DIR/matches_u8.rs:13:9: 13:13
+  
+      bb0: {
+          _2 = discriminant(_1);           // scope 0 at $DIR/matches_u8.rs:13:9: 13:13
+          switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:13:9: 13:13
+      }
+  
+      bb1: {
+          _0 = const 1_u8;                 // scope 0 at $DIR/matches_u8.rs:14:17: 14:18
+                                           // ty::Const
+                                           // + ty: u8
+                                           // + val: Value(Scalar(0x01))
+                                           // mir::Constant
+                                           // + span: $DIR/matches_u8.rs:14:17: 14:18
+                                           // + literal: Const { ty: u8, val: Value(Scalar(0x01)) }
+          goto -> bb3;                     // scope 0 at $DIR/matches_u8.rs:12:5: 15:6
+      }
+  
+      bb2: {
+          _0 = const 0_u8;                 // scope 0 at $DIR/matches_u8.rs:13:17: 13:18
+                                           // ty::Const
+                                           // + ty: u8
+                                           // + val: Value(Scalar(0x00))
+                                           // mir::Constant
+                                           // + span: $DIR/matches_u8.rs:13:17: 13:18
+                                           // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
+          goto -> bb3;                     // scope 0 at $DIR/matches_u8.rs:12:5: 15:6
+      }
+  
+      bb3: {
+          return;                          // scope 0 at $DIR/matches_u8.rs:16:2: 16:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff.64bit b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff.64bit
new file mode 100644
index 00000000000..c41bd999dc9
--- /dev/null
+++ b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff.64bit
@@ -0,0 +1,40 @@
+- // MIR for `exhaustive_match` before MatchBranchSimplification
++ // MIR for `exhaustive_match` after MatchBranchSimplification
+  
+  fn exhaustive_match(_1: E) -> u8 {
+      debug e => _1;                       // in scope 0 at $DIR/matches_u8.rs:11:25: 11:26
+      let mut _0: u8;                      // return place in scope 0 at $DIR/matches_u8.rs:11:34: 11:36
+      let mut _2: isize;                   // in scope 0 at $DIR/matches_u8.rs:13:9: 13:13
+  
+      bb0: {
+          _2 = discriminant(_1);           // scope 0 at $DIR/matches_u8.rs:13:9: 13:13
+          switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:13:9: 13:13
+      }
+  
+      bb1: {
+          _0 = const 1_u8;                 // scope 0 at $DIR/matches_u8.rs:14:17: 14:18
+                                           // ty::Const
+                                           // + ty: u8
+                                           // + val: Value(Scalar(0x01))
+                                           // mir::Constant
+                                           // + span: $DIR/matches_u8.rs:14:17: 14:18
+                                           // + literal: Const { ty: u8, val: Value(Scalar(0x01)) }
+          goto -> bb3;                     // scope 0 at $DIR/matches_u8.rs:12:5: 15:6
+      }
+  
+      bb2: {
+          _0 = const 0_u8;                 // scope 0 at $DIR/matches_u8.rs:13:17: 13:18
+                                           // ty::Const
+                                           // + ty: u8
+                                           // + val: Value(Scalar(0x00))
+                                           // mir::Constant
+                                           // + span: $DIR/matches_u8.rs:13:17: 13:18
+                                           // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
+          goto -> bb3;                     // scope 0 at $DIR/matches_u8.rs:12:5: 15:6
+      }
+  
+      bb3: {
+          return;                          // scope 0 at $DIR/matches_u8.rs:16:2: 16:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff.32bit b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff.32bit
new file mode 100644
index 00000000000..2c4bbc8095e
--- /dev/null
+++ b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff.32bit
@@ -0,0 +1,40 @@
+- // MIR for `exhaustive_match_i8` before MatchBranchSimplification
++ // MIR for `exhaustive_match_i8` after MatchBranchSimplification
+  
+  fn exhaustive_match_i8(_1: E) -> i8 {
+      debug e => _1;                       // in scope 0 at $DIR/matches_u8.rs:19:28: 19:29
+      let mut _0: i8;                      // return place in scope 0 at $DIR/matches_u8.rs:19:37: 19:39
+      let mut _2: isize;                   // in scope 0 at $DIR/matches_u8.rs:21:9: 21:13
+  
+      bb0: {
+          _2 = discriminant(_1);           // scope 0 at $DIR/matches_u8.rs:21:9: 21:13
+          switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:21:9: 21:13
+      }
+  
+      bb1: {
+          _0 = const 1_i8;                 // scope 0 at $DIR/matches_u8.rs:22:17: 22:18
+                                           // ty::Const
+                                           // + ty: i8
+                                           // + val: Value(Scalar(0x01))
+                                           // mir::Constant
+                                           // + span: $DIR/matches_u8.rs:22:17: 22:18
+                                           // + literal: Const { ty: i8, val: Value(Scalar(0x01)) }
+          goto -> bb3;                     // scope 0 at $DIR/matches_u8.rs:20:5: 23:6
+      }
+  
+      bb2: {
+          _0 = const 0_i8;                 // scope 0 at $DIR/matches_u8.rs:21:17: 21:18
+                                           // ty::Const
+                                           // + ty: i8
+                                           // + val: Value(Scalar(0x00))
+                                           // mir::Constant
+                                           // + span: $DIR/matches_u8.rs:21:17: 21:18
+                                           // + literal: Const { ty: i8, val: Value(Scalar(0x00)) }
+          goto -> bb3;                     // scope 0 at $DIR/matches_u8.rs:20:5: 23:6
+      }
+  
+      bb3: {
+          return;                          // scope 0 at $DIR/matches_u8.rs:24:2: 24:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff.64bit b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff.64bit
new file mode 100644
index 00000000000..2c4bbc8095e
--- /dev/null
+++ b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff.64bit
@@ -0,0 +1,40 @@
+- // MIR for `exhaustive_match_i8` before MatchBranchSimplification
++ // MIR for `exhaustive_match_i8` after MatchBranchSimplification
+  
+  fn exhaustive_match_i8(_1: E) -> i8 {
+      debug e => _1;                       // in scope 0 at $DIR/matches_u8.rs:19:28: 19:29
+      let mut _0: i8;                      // return place in scope 0 at $DIR/matches_u8.rs:19:37: 19:39
+      let mut _2: isize;                   // in scope 0 at $DIR/matches_u8.rs:21:9: 21:13
+  
+      bb0: {
+          _2 = discriminant(_1);           // scope 0 at $DIR/matches_u8.rs:21:9: 21:13
+          switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:21:9: 21:13
+      }
+  
+      bb1: {
+          _0 = const 1_i8;                 // scope 0 at $DIR/matches_u8.rs:22:17: 22:18
+                                           // ty::Const
+                                           // + ty: i8
+                                           // + val: Value(Scalar(0x01))
+                                           // mir::Constant
+                                           // + span: $DIR/matches_u8.rs:22:17: 22:18
+                                           // + literal: Const { ty: i8, val: Value(Scalar(0x01)) }
+          goto -> bb3;                     // scope 0 at $DIR/matches_u8.rs:20:5: 23:6
+      }
+  
+      bb2: {
+          _0 = const 0_i8;                 // scope 0 at $DIR/matches_u8.rs:21:17: 21:18
+                                           // ty::Const
+                                           // + ty: i8
+                                           // + val: Value(Scalar(0x00))
+                                           // mir::Constant
+                                           // + span: $DIR/matches_u8.rs:21:17: 21:18
+                                           // + literal: Const { ty: i8, val: Value(Scalar(0x00)) }
+          goto -> bb3;                     // scope 0 at $DIR/matches_u8.rs:20:5: 23:6
+      }
+  
+      bb3: {
+          return;                          // scope 0 at $DIR/matches_u8.rs:24:2: 24:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/matches_u8.rs b/src/test/mir-opt/matches_u8.rs
index 15de01fa963..78373be48b6 100644
--- a/src/test/mir-opt/matches_u8.rs
+++ b/src/test/mir-opt/matches_u8.rs
@@ -1,12 +1,12 @@
 // EMIT_MIR_FOR_EACH_BIT_WIDTH
 // EMIT_MIR matches_u8.exhaustive_match.MatchBranchSimplification.diff
+// EMIT_MIR matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
 
 pub enum E {
     A,
     B,
 }
 
-// This only breaks on u8's, but probably still have to test i8.
 #[no_mangle]
 pub fn exhaustive_match(e: E) -> u8 {
     match e {
@@ -15,7 +15,18 @@ pub fn exhaustive_match(e: E) -> u8 {
     }
 }
 
+#[no_mangle]
+pub fn exhaustive_match_i8(e: E) -> i8 {
+    match e {
+        E::A => 0,
+        E::B => 1,
+    }
+}
+
 fn main() {
   assert_eq!(exhaustive_match(E::A), 0);
   assert_eq!(exhaustive_match(E::B), 1);
+
+  assert_eq!(exhaustive_match_i8(E::A), 0);
+  assert_eq!(exhaustive_match_i8(E::B), 1);
 }