about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_prop.rs13
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff7
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff7
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir15
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir15
-rw-r--r--tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir5
-rw-r--r--tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff45
-rw-r--r--tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff45
-rw-r--r--tests/mir-opt/unreachable.if_let.UnreachablePropagation.panic-abort.diff (renamed from tests/mir-opt/unreachable.main.UnreachablePropagation.panic-abort.diff)11
-rw-r--r--tests/mir-opt/unreachable.if_let.UnreachablePropagation.panic-unwind.diff (renamed from tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff)11
-rw-r--r--tests/mir-opt/unreachable.rs32
11 files changed, 148 insertions, 58 deletions
diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs
index d25c6d471cd..919e8d6a234 100644
--- a/compiler/rustc_mir_transform/src/unreachable_prop.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs
@@ -116,22 +116,21 @@ fn remove_successors_from_switch<'tcx>(
         patch.add_statement(location, StatementKind::Intrinsic(Box::new(assume)));
     };
 
+    let otherwise = targets.otherwise();
+    let otherwise_unreachable = is_unreachable(otherwise);
+
     let reachable_iter = targets.iter().filter(|&(value, bb)| {
         let is_unreachable = is_unreachable(bb);
-        if is_unreachable {
-            // We remove this target from the switch, so record the inequality using `Assume`.
+        // We remove this target from the switch, so record the inequality using `Assume`.
+        if is_unreachable && !otherwise_unreachable {
             add_assumption(BinOp::Ne, value);
-            false
-        } else {
-            true
         }
+        !is_unreachable
     });
 
-    let otherwise = targets.otherwise();
     let new_targets = SwitchTargets::new(reachable_iter, otherwise);
 
     let num_targets = new_targets.all_targets().len();
-    let otherwise_unreachable = is_unreachable(otherwise);
     let fully_unreachable = num_targets == 1 && otherwise_unreachable;
 
     let terminator = match (num_targets, otherwise_unreachable) {
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
index 4ca7a2c4294..2a36ad9230e 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
@@ -10,7 +10,6 @@
 +         let mut _3: &std::option::Option<T>;
 +         let mut _4: isize;
 +         let mut _5: bool;
-+         let mut _6: bool;
 +         scope 2 {
 +             debug val => _0;
 +         }
@@ -37,14 +36,10 @@
 +         StorageLive(_3);
 +         StorageLive(_4);
 +         StorageLive(_5);
-+         StorageLive(_6);
 +         _4 = discriminant(_2);
-+         _5 = Ne(_4, const 0_isize);
++         _5 = Eq(_4, const 1_isize);
 +         assume(move _5);
-+         _6 = Eq(_4, const 1_isize);
-+         assume(move _6);
 +         _0 = move ((_2 as Some).0: T);
-+         StorageDead(_6);
 +         StorageDead(_5);
 +         StorageDead(_4);
 +         StorageDead(_3);
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
index caabb7ea463..14c8c671d3f 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
@@ -10,7 +10,6 @@
 +         let mut _3: &std::option::Option<T>;
 +         let mut _4: isize;
 +         let mut _5: bool;
-+         let mut _6: bool;
 +         scope 2 {
 +             debug val => _0;
 +         }
@@ -37,14 +36,10 @@
 +         StorageLive(_3);
 +         StorageLive(_4);
 +         StorageLive(_5);
-+         StorageLive(_6);
 +         _4 = discriminant(_2);
-+         _5 = Ne(_4, const 0_isize);
++         _5 = Eq(_4, const 1_isize);
 +         assume(move _5);
-+         _6 = Eq(_4, const 1_isize);
-+         assume(move _6);
 +         _0 = move ((_2 as Some).0: T);
-+         StorageDead(_6);
 +         StorageDead(_5);
 +         StorageDead(_4);
 +         StorageDead(_3);
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
index 521266925e0..aeb93bd334f 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
@@ -7,8 +7,7 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
         debug self => _1;
         let mut _2: isize;
         let mut _3: bool;
-        let mut _4: bool;
-        let mut _5: &std::option::Option<T>;
+        let mut _4: &std::option::Option<T>;
         scope 2 {
             debug val => _0;
         }
@@ -21,25 +20,21 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
             }
         }
         scope 4 (inlined Option::<T>::is_some) {
-            debug self => _5;
+            debug self => _4;
         }
     }
 
     bb0: {
-        StorageLive(_5);
+        StorageLive(_4);
         StorageLive(_2);
         StorageLive(_3);
-        StorageLive(_4);
         _2 = discriminant(_1);
-        _3 = Ne(_2, const 0_isize);
+        _3 = Eq(_2, const 1_isize);
         assume(move _3);
-        _4 = Eq(_2, const 1_isize);
-        assume(move _4);
         _0 = move ((_1 as Some).0: T);
-        StorageDead(_4);
         StorageDead(_3);
         StorageDead(_2);
-        StorageDead(_5);
+        StorageDead(_4);
         return;
     }
 }
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
index 521266925e0..aeb93bd334f 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
@@ -7,8 +7,7 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
         debug self => _1;
         let mut _2: isize;
         let mut _3: bool;
-        let mut _4: bool;
-        let mut _5: &std::option::Option<T>;
+        let mut _4: &std::option::Option<T>;
         scope 2 {
             debug val => _0;
         }
@@ -21,25 +20,21 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
             }
         }
         scope 4 (inlined Option::<T>::is_some) {
-            debug self => _5;
+            debug self => _4;
         }
     }
 
     bb0: {
-        StorageLive(_5);
+        StorageLive(_4);
         StorageLive(_2);
         StorageLive(_3);
-        StorageLive(_4);
         _2 = discriminant(_1);
-        _3 = Ne(_2, const 0_isize);
+        _3 = Eq(_2, const 1_isize);
         assume(move _3);
-        _4 = Eq(_2, const 1_isize);
-        assume(move _4);
         _0 = move ((_1 as Some).0: T);
-        StorageDead(_4);
         StorageDead(_3);
         StorageDead(_2);
-        StorageDead(_5);
+        StorageDead(_4);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
index fe7beadc818..0114309dbb5 100644
--- a/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
@@ -5,7 +5,6 @@ fn ub_if_b(_1: Thing) -> Thing {
     let mut _0: Thing;
     let mut _2: isize;
     let mut _3: bool;
-    let mut _4: bool;
     scope 1 (inlined unreachable_unchecked) {
         scope 2 {
             scope 3 (inlined unreachable_unchecked::runtime) {
@@ -15,10 +14,8 @@ fn ub_if_b(_1: Thing) -> Thing {
 
     bb0: {
         _2 = discriminant(_1);
-        _3 = Ne(_2, const 1_isize);
+        _3 = Eq(_2, const 0_isize);
         assume(move _3);
-        _4 = Eq(_2, const 0_isize);
-        assume(move _4);
         _0 = move _1;
         return;
     }
diff --git a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff
new file mode 100644
index 00000000000..f6e594ffac7
--- /dev/null
+++ b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff
@@ -0,0 +1,45 @@
+- // MIR for `as_match` before UnreachablePropagation
++ // MIR for `as_match` after UnreachablePropagation
+  
+  fn as_match() -> () {
+      let mut _0: ();
+      let mut _1: std::option::Option<Empty>;
+      let mut _2: isize;
+      let _3: Empty;
+      let mut _4: !;
++     let mut _5: bool;
+      scope 1 {
+          debug _x => _3;
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          _1 = empty() -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          _2 = discriminant(_1);
+-         switchInt(move _2) -> [0: bb4, 1: bb2, otherwise: bb3];
++         _5 = Eq(_2, const 0_isize);
++         assume(move _5);
++         goto -> bb4;
+      }
+  
+      bb2: {
+-         StorageLive(_3);
+-         _3 = move ((_1 as Some).0: Empty);
+-         StorageLive(_4);
+          unreachable;
+      }
+  
+      bb3: {
+          unreachable;
+      }
+  
+      bb4: {
+          _0 = const ();
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff
new file mode 100644
index 00000000000..2813d64672e
--- /dev/null
+++ b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff
@@ -0,0 +1,45 @@
+- // MIR for `as_match` before UnreachablePropagation
++ // MIR for `as_match` after UnreachablePropagation
+  
+  fn as_match() -> () {
+      let mut _0: ();
+      let mut _1: std::option::Option<Empty>;
+      let mut _2: isize;
+      let _3: Empty;
+      let mut _4: !;
++     let mut _5: bool;
+      scope 1 {
+          debug _x => _3;
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          _1 = empty() -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+          _2 = discriminant(_1);
+-         switchInt(move _2) -> [0: bb4, 1: bb2, otherwise: bb3];
++         _5 = Eq(_2, const 0_isize);
++         assume(move _5);
++         goto -> bb4;
+      }
+  
+      bb2: {
+-         StorageLive(_3);
+-         _3 = move ((_1 as Some).0: Empty);
+-         StorageLive(_4);
+          unreachable;
+      }
+  
+      bb3: {
+          unreachable;
+      }
+  
+      bb4: {
+          _0 = const ();
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-abort.diff b/tests/mir-opt/unreachable.if_let.UnreachablePropagation.panic-abort.diff
index 6f4faefce14..61959732720 100644
--- a/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-abort.diff
+++ b/tests/mir-opt/unreachable.if_let.UnreachablePropagation.panic-abort.diff
@@ -1,7 +1,7 @@
-- // MIR for `main` before UnreachablePropagation
-+ // MIR for `main` after UnreachablePropagation
+- // MIR for `if_let` before UnreachablePropagation
++ // MIR for `if_let` after UnreachablePropagation
   
-  fn main() -> () {
+  fn if_let() -> () {
       let mut _0: ();
       let mut _1: std::option::Option<Empty>;
       let mut _2: isize;
@@ -9,7 +9,6 @@
       let mut _6: bool;
       let mut _7: !;
 +     let mut _8: bool;
-+     let mut _9: bool;
       scope 1 {
           debug _x => _3;
           let _3: Empty;
@@ -27,8 +26,8 @@
       bb1: {
           _2 = discriminant(_1);
 -         switchInt(move _2) -> [1: bb2, otherwise: bb6];
-+         _9 = Ne(_2, const 1_isize);
-+         assume(move _9);
++         _8 = Ne(_2, const 1_isize);
++         assume(move _8);
 +         goto -> bb6;
       }
   
diff --git a/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff b/tests/mir-opt/unreachable.if_let.UnreachablePropagation.panic-unwind.diff
index 5bacb42bed3..476e2f55994 100644
--- a/tests/mir-opt/unreachable.main.UnreachablePropagation.panic-unwind.diff
+++ b/tests/mir-opt/unreachable.if_let.UnreachablePropagation.panic-unwind.diff
@@ -1,7 +1,7 @@
-- // MIR for `main` before UnreachablePropagation
-+ // MIR for `main` after UnreachablePropagation
+- // MIR for `if_let` before UnreachablePropagation
++ // MIR for `if_let` after UnreachablePropagation
   
-  fn main() -> () {
+  fn if_let() -> () {
       let mut _0: ();
       let mut _1: std::option::Option<Empty>;
       let mut _2: isize;
@@ -9,7 +9,6 @@
       let mut _6: bool;
       let mut _7: !;
 +     let mut _8: bool;
-+     let mut _9: bool;
       scope 1 {
           debug _x => _3;
           let _3: Empty;
@@ -27,8 +26,8 @@
       bb1: {
           _2 = discriminant(_1);
 -         switchInt(move _2) -> [1: bb2, otherwise: bb6];
-+         _9 = Ne(_2, const 1_isize);
-+         assume(move _9);
++         _8 = Ne(_2, const 1_isize);
++         assume(move _8);
 +         goto -> bb6;
       }
   
diff --git a/tests/mir-opt/unreachable.rs b/tests/mir-opt/unreachable.rs
index 3d934ace261..5b96681d9df 100644
--- a/tests/mir-opt/unreachable.rs
+++ b/tests/mir-opt/unreachable.rs
@@ -7,9 +7,9 @@ fn empty() -> Option<Empty> {
     None
 }
 
-// EMIT_MIR unreachable.main.UnreachablePropagation.diff
-fn main() {
-    // CHECK-LABEL: fn main(
+// EMIT_MIR unreachable.if_let.UnreachablePropagation.diff
+fn if_let() {
+    // CHECK-LABEL: fn if_let(
     // CHECK: bb0: {
     // CHECK: {{_.*}} = empty()
     // CHECK: bb1: {
@@ -38,3 +38,29 @@ fn main() {
         match _x { }
     }
 }
+
+// EMIT_MIR unreachable.as_match.UnreachablePropagation.diff
+fn as_match() {
+    // CHECK-LABEL: fn as_match(
+    // CHECK: bb0: {
+    // CHECK: {{_.*}} = empty()
+    // CHECK: bb1: {
+    // CHECK: [[eq:_.*]] = Eq({{.*}}, const 0_isize);
+    // CHECK-NEXT: assume(move [[eq]]);
+    // CHECK-NEXT: goto -> bb4;
+    // CHECK: bb2: {
+    // CHECK-NEXT: unreachable;
+    // CHECK: bb3: {
+    // CHECK-NEXT: unreachable;
+    // CHECK: bb4: {
+    // CHECK: return;
+    match empty() {
+        None => {}
+        Some(_x) => match _x {}
+    }
+}
+
+fn main() {
+    if_let();
+    as_match();
+}