about summary refs log tree commit diff
diff options
context:
space:
mode:
authorShunpoco <tkngsnsk313320@gmail.com>2025-01-12 14:10:26 +0000
committerShunpoco <tkngsnsk313320@gmail.com>2025-01-12 14:45:09 +0000
commit3a83422c136533592618da1ec0a2abee0ef5e5d9 (patch)
tree62022b9afde1b94b1a3b6d8adf994b8fde983680
parent13f3924c675f5a678a849ac87412710b8bca6636 (diff)
downloadrust-3a83422c136533592618da1ec0a2abee0ef5e5d9.tar.gz
rust-3a83422c136533592618da1ec0a2abee0ef5e5d9.zip
Fix ICE-133063
If all subcandidates have never-pattern, the parent candidate should have otherwise_block
because some methods expect the candidate has the block.

Signed-off-by: Shunpoco <tkngsnsk313320@gmail.com>
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/mod.rs8
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/ICE-133063-never-arm-no-otherwise-block.rs21
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/ICE-133063-never-arm-no-otherwise-block.stderr37
3 files changed, 63 insertions, 3 deletions
diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs
index b944d13fb0d..4b8d33c0dd6 100644
--- a/compiler/rustc_mir_build/src/builder/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs
@@ -1958,7 +1958,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // This candidate is about to become a leaf, so unset `or_span`.
         let or_span = candidate.or_span.take().unwrap();
         let source_info = self.source_info(or_span);
-
+        
         if candidate.false_edge_start_block.is_none() {
             candidate.false_edge_start_block = candidate.subcandidates[0].false_edge_start_block;
         }
@@ -2000,8 +2000,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
         });
         if candidate.subcandidates.is_empty() {
-            // If `candidate` has become a leaf candidate, ensure it has a `pre_binding_block`.
-            candidate.pre_binding_block = Some(self.cfg.start_new_block());
+            // If `candidate` has become a leaf candidate, ensure it has a `pre_binding_block` and `otherwise_block`.
+            let next_block = self.cfg.start_new_block();
+            candidate.pre_binding_block = Some(next_block);
+            candidate.otherwise_block = Some(next_block);
         }
     }
 
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133063-never-arm-no-otherwise-block.rs b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133063-never-arm-no-otherwise-block.rs
new file mode 100644
index 00000000000..a9527d7d0c4
--- /dev/null
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133063-never-arm-no-otherwise-block.rs
@@ -0,0 +1,21 @@
+#![feature(never_patterns)]
+#![feature(if_let_guard)]
+#![allow(incomplete_features)]
+
+fn split_last(_: &()) -> Option<(&i32, &i32)> {
+    None
+}
+
+fn assign_twice() {
+    loop {
+        match () {
+            (!| //~ ERROR: mismatched types
+            !) if let _ = split_last(&()) => {} //~ ERROR a never pattern is always unreachable
+            //~^ ERROR: mismatched types
+            //~^^ WARNING: irrefutable `if let` guard pattern [irrefutable_let_patterns]
+            _ => {}
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133063-never-arm-no-otherwise-block.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133063-never-arm-no-otherwise-block.stderr
new file mode 100644
index 00000000000..896c95f1866
--- /dev/null
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133063-never-arm-no-otherwise-block.stderr
@@ -0,0 +1,37 @@
+error: a never pattern is always unreachable
+  --> $DIR/ICE-133063-never-arm-no-otherwise-block.rs:13:46
+   |
+LL |             !) if let _ = split_last(&()) => {}
+   |                                              ^^
+   |                                              |
+   |                                              this will never be executed
+   |                                              help: remove this expression
+
+error: mismatched types
+  --> $DIR/ICE-133063-never-arm-no-otherwise-block.rs:12:14
+   |
+LL |             (!|
+   |              ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `()`
+
+error: mismatched types
+  --> $DIR/ICE-133063-never-arm-no-otherwise-block.rs:13:13
+   |
+LL |             !) if let _ = split_last(&()) => {}
+   |             ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `()`
+
+warning: irrefutable `if let` guard pattern
+  --> $DIR/ICE-133063-never-arm-no-otherwise-block.rs:13:19
+   |
+LL |             !) if let _ = split_last(&()) => {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this pattern will always match, so the guard is useless
+   = help: consider removing the guard and adding a `let` inside the match arm
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
+
+error: aborting due to 3 previous errors; 1 warning emitted
+