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.
This commit is contained in:
kadmin 2020-08-14 00:11:36 +00:00
parent c0a811a24e
commit fd740266de
6 changed files with 179 additions and 10 deletions

View File

@ -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;
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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);
}