Skip to content

Commit 457f8ba

Browse files
committed
mir-opt: Do not transform non-int type in match_branches
1 parent 80c3498 commit 457f8ba

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

compiler/rustc_mir_transform/src/match_branches.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,14 @@ fn can_cast(
284284
let v = match src_layout.ty.kind() {
285285
ty::Uint(_) => from_scalar.to_uint(src_layout.size),
286286
ty::Int(_) => from_scalar.to_int(src_layout.size) as u128,
287-
_ => unreachable!("invalid int"),
287+
// We can also transform the values of other integer representations (such as char),
288+
// although this may not be practical in real-world scenarios.
289+
_ => return false,
288290
};
289291
let size = match *cast_ty.kind() {
290292
ty::Int(t) => Integer::from_int_ty(&tcx, t).size(),
291293
ty::Uint(t) => Integer::from_uint_ty(&tcx, t).size(),
292-
_ => unreachable!("invalid int"),
294+
_ => return false,
293295
};
294296
let v = size.truncate(v);
295297
let cast_scalar = ScalarInt::try_from_uint(v, size).unwrap();
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
- // MIR for `match_non_int_failed` before MatchBranchSimplification
2+
+ // MIR for `match_non_int_failed` after MatchBranchSimplification
3+
4+
fn match_non_int_failed(_1: char) -> u8 {
5+
let mut _0: u8;
6+
7+
bb0: {
8+
switchInt(copy _1) -> [97: bb1, 98: bb2, otherwise: bb3];
9+
}
10+
11+
bb1: {
12+
_0 = const 97_u8;
13+
goto -> bb4;
14+
}
15+
16+
bb2: {
17+
_0 = const 98_u8;
18+
goto -> bb4;
19+
}
20+
21+
bb3: {
22+
unreachable;
23+
}
24+
25+
bb4: {
26+
return;
27+
}
28+
}
29+

tests/mir-opt/matches_reduce_branches.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,37 @@ fn match_i128_u128(i: EnumAi128) -> u128 {
628628
}
629629
}
630630

631+
// EMIT_MIR matches_reduce_branches.match_non_int_failed.MatchBranchSimplification.diff
632+
#[custom_mir(dialect = "runtime")]
633+
fn match_non_int_failed(i: char) -> u8 {
634+
// CHECK-LABEL: fn match_non_int_failed(
635+
// CHECK: switchInt
636+
// CHECK: return
637+
mir! {
638+
{
639+
match i {
640+
'a' => bb1,
641+
'b' => bb2,
642+
_ => unreachable_bb,
643+
}
644+
}
645+
bb1 = {
646+
RET = 97;
647+
Goto(ret)
648+
}
649+
bb2 = {
650+
RET = 98;
651+
Goto(ret)
652+
}
653+
unreachable_bb = {
654+
Unreachable()
655+
}
656+
ret = {
657+
Return()
658+
}
659+
}
660+
}
661+
631662
fn main() {
632663
let _ = foo(None);
633664
let _ = foo(Some(()));
@@ -665,4 +696,5 @@ fn main() {
665696
let _ = match_i128_u128(EnumAi128::A);
666697

667698
let _ = my_is_some(None);
699+
let _ = match_non_int_failed('a');
668700
}

0 commit comments

Comments
 (0)