-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of #135409 - Shunpoco:issue-133117-ICE-never-false-edge-…
…start-block, r=Nadrieril Fix ICE-133117: multiple never-pattern arm doesn't have false_edge_start_block Fixes #133117 , and close fixes #133063 , fixes #130779 In order to fix ICE-133117, at first I needed to tackle to ICE-133063 (this fixed 130779 as well). ### ICE-133063 and ICE-130779 This ICE is caused by those steps: 1. An arm has or-pattern, and all of the sub-candidates are never-pattern 2. In that case, all sub-candidates are removed in remove_never_subcandidates(). So the arm (candidate) has no sub-candidate. 3. In the current implementation, if there is no sub-candidate, the function assigns `pre_binding_block` into the candidate ([here](https://github.com/rust-lang/rust/blob/master/compiler/rustc_mir_build/src/builder/matches/mod.rs#L2002-L2004)). However, otherwise_block should be assigned to the candidate as well, because the otherwise_block is unwrapped in multiple place (like in lower_match_tree()). As a result, it causes the panic. I simply added the same block as pre_binding_block into otherwise_block, but I'm wondering if there is a better block to assign to otherwise_block (is it ok to assign the same block into pre_binding and otherwise?) ### ICE-133117 This is caused by those steps: 1. There are two arms, both are or-pattern and each has one match-pair (in the test code, both are `(!|!)`), and the second arm has a guard. 2. In match_candidate() for the first arm, it expands the second arm’s sub-candidates as well ([here](https://github.com/rust-lang/rust/blob/master/compiler/rustc_mir_build/src/builder/matches/mod.rs#L1800-L1805)). As a result, the root candidate of the second arm is not evaluated/modified in match_candidate(). So a false_edge_start_block is not assigned to the candidate. 3. merge_trivial_subcandidates() is called against the candidate for the second arm. It just returns immediately because the candidate has a guard. So a flase_edge_start_block is not assigned to the candidate also in this function. 4. remove_never_subcandidates() is called against the candidate. Since all sub-candidates are never-pattern. they are removed. 5. In lower_match_tree(), since there is no sub-candidate for the candidate, the candidate itself is evaluated in visit_leave_rev ([here](https://github.com/rust-lang/rust/blob/master/compiler/rustc_mir_build/src/builder/matches/mod.rs#L1532)). Because the candidate has no false_edge_start_block, it causes the panic. So I modified the order of if blocks in merge_trivial_subcandidates() to assign a false_edge_start_block if the candidate doesn't have.
- Loading branch information
Showing
10 changed files
with
115 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
12 changes: 12 additions & 0 deletions
12
tests/ui/rfcs/rfc-0000-never_patterns/ICE-130779-never-arm-no-oatherwise-block.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#![feature(never_patterns)] | ||
#![allow(incomplete_features)] | ||
|
||
enum E { A } | ||
|
||
fn main() { | ||
match E::A { | ||
! | //~ ERROR: a trailing `|` is not allowed in an or-pattern | ||
//~^ ERROR: mismatched types | ||
if true => {} //~ ERROR: a never pattern is always unreachable | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
tests/ui/rfcs/rfc-0000-never_patterns/ICE-130779-never-arm-no-oatherwise-block.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
error: a trailing `|` is not allowed in an or-pattern | ||
--> $DIR/ICE-130779-never-arm-no-oatherwise-block.rs:8:11 | ||
| | ||
LL | ! | | ||
| - ^ | ||
| | | ||
| while parsing this or-pattern starting here | ||
| | ||
help: remove the `|` | ||
| | ||
LL - ! | | ||
LL + ! | ||
| | ||
|
||
error: a never pattern is always unreachable | ||
--> $DIR/ICE-130779-never-arm-no-oatherwise-block.rs:10:20 | ||
| | ||
LL | if true => {} | ||
| ^^ | ||
| | | ||
| this will never be executed | ||
| help: remove this expression | ||
|
||
error: mismatched types | ||
--> $DIR/ICE-130779-never-arm-no-oatherwise-block.rs:8:9 | ||
| | ||
LL | ! | | ||
| ^ a never pattern must be used on an uninhabited type | ||
| | ||
= note: the matched value is of type `E` | ||
|
||
error: aborting due to 3 previous errors | ||
|
16 changes: 16 additions & 0 deletions
16
tests/ui/rfcs/rfc-0000-never_patterns/ICE-133063-never-arm-no-otherwise-block.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#![feature(never_type)] | ||
#![feature(never_patterns)] | ||
#![allow(incomplete_features)] | ||
|
||
enum Void {} | ||
|
||
fn foo(x: Void) { | ||
loop { | ||
match x { | ||
(!|!) if false => {} //~ ERROR a never pattern is always unreachable | ||
_ => {} | ||
} | ||
} | ||
} | ||
|
||
fn main() {} |
11 changes: 11 additions & 0 deletions
11
tests/ui/rfcs/rfc-0000-never_patterns/ICE-133063-never-arm-no-otherwise-block.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
error: a never pattern is always unreachable | ||
--> $DIR/ICE-133063-never-arm-no-otherwise-block.rs:10:31 | ||
| | ||
LL | (!|!) if false => {} | ||
| ^^ | ||
| | | ||
| this will never be executed | ||
| help: remove this expression | ||
|
||
error: aborting due to 1 previous error | ||
|
14 changes: 14 additions & 0 deletions
14
tests/ui/rfcs/rfc-0000-never_patterns/ICE-133117-duplicate-never-arm.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#![feature(never_type)] | ||
#![feature(never_patterns)] | ||
#![allow(incomplete_features)] | ||
|
||
enum Void {} | ||
|
||
fn foo(x: Void) { | ||
match x { | ||
(!|!) if true => {} //~ ERROR a never pattern is always unreachable | ||
(!|!) if true => {} //~ ERROR a never pattern is always unreachable | ||
} | ||
} | ||
|
||
fn main() {} |
20 changes: 20 additions & 0 deletions
20
tests/ui/rfcs/rfc-0000-never_patterns/ICE-133117-duplicate-never-arm.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
error: a never pattern is always unreachable | ||
--> $DIR/ICE-133117-duplicate-never-arm.rs:9:26 | ||
| | ||
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: aborting due to 2 previous errors | ||
|