diff --git a/src/librustc_mir/transform/match_branches.rs b/src/librustc_mir/transform/match_branches.rs index 74da6d5e629b3..67021ae512b65 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 0000000000000..c41bd999dc9fc --- /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 0000000000000..c41bd999dc9fc --- /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 0000000000000..2c4bbc8095e9a --- /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 0000000000000..2c4bbc8095e9a --- /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 new file mode 100644 index 0000000000000..78373be48b685 --- /dev/null +++ b/src/test/mir-opt/matches_u8.rs @@ -0,0 +1,32 @@ +// 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, +} + +#[no_mangle] +pub fn exhaustive_match(e: E) -> u8 { + match e { + E::A => 0, + E::B => 1, + } +} + +#[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); +}