diff options
| author | Shunpoco <tkngsnsk313320@gmail.com> | 2025-01-12 14:44:36 +0000 |
|---|---|---|
| committer | Shunpoco <tkngsnsk313320@gmail.com> | 2025-01-12 14:45:09 +0000 |
| commit | 8a57fa634c46273dab0a283d2ee151735342c514 (patch) | |
| tree | 4945d7780a3e7fbbfe0534a29523b26bd155418c | |
| parent | 3a83422c136533592618da1ec0a2abee0ef5e5d9 (diff) | |
| download | rust-8a57fa634c46273dab0a283d2ee151735342c514.tar.gz rust-8a57fa634c46273dab0a283d2ee151735342c514.zip | |
Fix ICE-133117
If all subcandidates have never-pattern, we should assign false_edge_start_block to the parent candidate if it doesn't have. merge_trivial_subcandidates does so, but if the candidate has guard it returns before the assignment. Signed-off-by: Shunpoco <tkngsnsk313320@gmail.com>
3 files changed, 52 insertions, 4 deletions
diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 4b8d33c0dd6..7e7c5ceee93 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1940,6 +1940,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// in match tree lowering. fn merge_trivial_subcandidates(&mut self, candidate: &mut Candidate<'_, 'tcx>) { assert!(!candidate.subcandidates.is_empty()); + if candidate.false_edge_start_block.is_none() { + candidate.false_edge_start_block = candidate.subcandidates[0].false_edge_start_block; + } + if candidate.has_guard { // FIXME(or_patterns; matthewjasper) Don't give up if we have a guard. return; @@ -1958,10 +1962,6 @@ 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; - } // Remove the (known-trivial) subcandidates from the candidate tree, // so that they aren't visible after match tree lowering, and wire them diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133117-duplicate-never-arm.rs b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133117-duplicate-never-arm.rs new file mode 100644 index 00000000000..884dbacbaa9 --- /dev/null +++ b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133117-duplicate-never-arm.rs @@ -0,0 +1,12 @@ +#![feature(never_patterns)] +#![allow(incomplete_features)] + +fn main() { + match () { + (!| + //~^ ERROR: mismatched types + !) if true => {} //~ ERROR a never pattern is always unreachable + //~^ ERROR: mismatched types + (!|!) if true => {} //~ ERROR a never pattern is always unreachable + } +} diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133117-duplicate-never-arm.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133117-duplicate-never-arm.stderr new file mode 100644 index 00000000000..4b8de102a7b --- /dev/null +++ b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-133117-duplicate-never-arm.stderr @@ -0,0 +1,36 @@ +error: a never pattern is always unreachable + --> $DIR/ICE-133117-duplicate-never-arm.rs:8:23 + | +LL | !) if true => {} + | ^^ + | | + | this will never be executed + | help: remove this expression + +error: a never pattern is always unreachable + --> $DIR/ICE-133117-duplicate-never-arm.rs:10:26 + | +LL | (!|!) if true => {} + | ^^ + | | + | this will never be executed + | help: remove this expression + +error: mismatched types + --> $DIR/ICE-133117-duplicate-never-arm.rs:6:10 + | +LL | (!| + | ^ a never pattern must be used on an uninhabited type + | + = note: the matched value is of type `()` + +error: mismatched types + --> $DIR/ICE-133117-duplicate-never-arm.rs:8:9 + | +LL | !) if true => {} + | ^ a never pattern must be used on an uninhabited type + | + = note: the matched value is of type `()` + +error: aborting due to 4 previous errors + |
