about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee <workingjubilee@gmail.com>2025-05-30 13:52:26 -0700
committerGitHub <noreply@github.com>2025-05-30 13:52:26 -0700
commit3846f2f08f19105ecb1f7acc9bd8da70db6f4e1d (patch)
treeccead4fb0c34a5c360298834205f66d45c0c22b2
parenta1d70ed5b036e6083af99b6c9cf2abece2a791b0 (diff)
parent457f8ba447a2f2d3fc20ad2b0d779d49c9883485 (diff)
downloadrust-3846f2f08f19105ecb1f7acc9bd8da70db6f4e1d.tar.gz
rust-3846f2f08f19105ecb1f7acc9bd8da70db6f4e1d.zip
Rollup merge of #141494 - dianqk:match-br-non-int, r=wesleywiser
mir-opt: Do not transform non-int type in match_branches

Fixes #141378.

r? mir-opt
-rw-r--r--compiler/rustc_mir_transform/src/match_branches.rs6
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_non_int_failed.MatchBranchSimplification.diff29
-rw-r--r--tests/mir-opt/matches_reduce_branches.rs32
3 files changed, 65 insertions, 2 deletions
diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs
index 8c0c3096899..5e511f1a418 100644
--- a/compiler/rustc_mir_transform/src/match_branches.rs
+++ b/compiler/rustc_mir_transform/src/match_branches.rs
@@ -284,12 +284,14 @@ fn can_cast(
     let v = match src_layout.ty.kind() {
         ty::Uint(_) => from_scalar.to_uint(src_layout.size),
         ty::Int(_) => from_scalar.to_int(src_layout.size) as u128,
-        _ => unreachable!("invalid int"),
+        // We can also transform the values of other integer representations (such as char),
+        // although this may not be practical in real-world scenarios.
+        _ => return false,
     };
     let size = match *cast_ty.kind() {
         ty::Int(t) => Integer::from_int_ty(&tcx, t).size(),
         ty::Uint(t) => Integer::from_uint_ty(&tcx, t).size(),
-        _ => unreachable!("invalid int"),
+        _ => return false,
     };
     let v = size.truncate(v);
     let cast_scalar = ScalarInt::try_from_uint(v, size).unwrap();
diff --git a/tests/mir-opt/matches_reduce_branches.match_non_int_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_non_int_failed.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..81e900a34c0
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_non_int_failed.MatchBranchSimplification.diff
@@ -0,0 +1,29 @@
+- // MIR for `match_non_int_failed` before MatchBranchSimplification
++ // MIR for `match_non_int_failed` after MatchBranchSimplification
+  
+  fn match_non_int_failed(_1: char) -> u8 {
+      let mut _0: u8;
+  
+      bb0: {
+          switchInt(copy _1) -> [97: bb1, 98: bb2, otherwise: bb3];
+      }
+  
+      bb1: {
+          _0 = const 97_u8;
+          goto -> bb4;
+      }
+  
+      bb2: {
+          _0 = const 98_u8;
+          goto -> bb4;
+      }
+  
+      bb3: {
+          unreachable;
+      }
+  
+      bb4: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.rs b/tests/mir-opt/matches_reduce_branches.rs
index 00131b0116d..89ef3bfb308 100644
--- a/tests/mir-opt/matches_reduce_branches.rs
+++ b/tests/mir-opt/matches_reduce_branches.rs
@@ -627,6 +627,37 @@ fn match_i128_u128(i: EnumAi128) -> u128 {
     }
 }
 
+// EMIT_MIR matches_reduce_branches.match_non_int_failed.MatchBranchSimplification.diff
+#[custom_mir(dialect = "runtime")]
+fn match_non_int_failed(i: char) -> u8 {
+    // CHECK-LABEL: fn match_non_int_failed(
+    // CHECK: switchInt
+    // CHECK: return
+    mir! {
+        {
+            match i {
+                'a' => bb1,
+                'b' => bb2,
+                _ => unreachable_bb,
+            }
+        }
+        bb1 = {
+            RET = 97;
+            Goto(ret)
+        }
+        bb2 = {
+            RET = 98;
+            Goto(ret)
+        }
+        unreachable_bb = {
+            Unreachable()
+        }
+        ret = {
+            Return()
+        }
+    }
+}
+
 fn main() {
     let _ = foo(None);
     let _ = foo(Some(()));
@@ -664,4 +695,5 @@ fn main() {
     let _ = match_i128_u128(EnumAi128::A);
 
     let _ = my_is_some(None);
+    let _ = match_non_int_failed('a');
 }