@@ -4,7 +4,8 @@ use crate::MirPass;
4
4
use rustc_data_structures:: fx:: FxHashSet ;
5
5
use rustc_middle:: mir:: patch:: MirPatch ;
6
6
use rustc_middle:: mir:: {
7
- BasicBlockData , Body , Local , Operand , Rvalue , StatementKind , TerminatorKind ,
7
+ BasicBlock , BasicBlockData , BasicBlocks , Body , Local , Operand , Rvalue , StatementKind ,
8
+ TerminatorKind ,
8
9
} ;
9
10
use rustc_middle:: ty:: layout:: TyAndLayout ;
10
11
use rustc_middle:: ty:: { Ty , TyCtxt } ;
@@ -118,9 +119,28 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
118
119
unreachable_targets. push ( index) ;
119
120
}
120
121
}
121
-
122
- let replace_otherwise_to_unreachable = allowed_variants. len ( ) <= 1
123
- && !body. basic_blocks [ targets. otherwise ( ) ] . is_empty_unreachable ( ) ;
122
+ let otherwise_is_empty_unreachable =
123
+ body. basic_blocks [ targets. otherwise ( ) ] . is_empty_unreachable ( ) ;
124
+ // After resolving https://github.com/llvm/llvm-project/issues/78578,
125
+ // we can remove the limit on the number of successors.
126
+ fn check_successors ( basic_blocks : & BasicBlocks < ' _ > , bb : BasicBlock ) -> bool {
127
+ let mut successors = basic_blocks[ bb] . terminator ( ) . successors ( ) ;
128
+ let Some ( first_successor) = successors. next ( ) else { return true } ;
129
+ if successors. next ( ) . is_some ( ) {
130
+ return true ;
131
+ }
132
+ if let TerminatorKind :: SwitchInt { .. } =
133
+ & basic_blocks[ first_successor] . terminator ( ) . kind
134
+ {
135
+ return false ;
136
+ } ;
137
+ true
138
+ }
139
+ let otherwise_is_last_variant = !otherwise_is_empty_unreachable
140
+ && allowed_variants. len ( ) == 1
141
+ && check_successors ( & body. basic_blocks , targets. otherwise ( ) ) ;
142
+ let replace_otherwise_to_unreachable = otherwise_is_last_variant
143
+ || !otherwise_is_empty_unreachable && allowed_variants. is_empty ( ) ;
124
144
125
145
if unreachable_targets. is_empty ( ) && !replace_otherwise_to_unreachable {
126
146
continue ;
@@ -129,7 +149,6 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
129
149
let unreachable_block = patch. unreachable_no_cleanup_block ( ) ;
130
150
let mut targets = targets. clone ( ) ;
131
151
if replace_otherwise_to_unreachable {
132
- let otherwise_is_last_variant = !allowed_variants. is_empty ( ) ;
133
152
if otherwise_is_last_variant {
134
153
#[ allow( rustc:: potential_query_instability) ]
135
154
let last_variant = * allowed_variants. iter ( ) . next ( ) . unwrap ( ) ;
0 commit comments