@@ -78,6 +78,7 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
7878 trace ! ( "UninhabitedEnumBranching starting for {:?}" , body. source) ;
7979
8080 let mut removable_switchs = Vec :: new ( ) ;
81+ let mut otherwise_is_last_variant_switchs = Vec :: new ( ) ;
8182
8283 for ( bb, bb_data) in body. basic_blocks . iter_enumerated ( ) {
8384 trace ! ( "processing block {:?}" , bb) ;
@@ -92,7 +93,7 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
9293 tcx. param_env_reveal_all_normalized ( body. source . def_id ( ) ) . and ( discriminant_ty) ,
9394 ) ;
9495
95- let allowed_variants = if let Ok ( layout) = layout {
96+ let mut allowed_variants = if let Ok ( layout) = layout {
9697 variant_discriminants ( & layout, discriminant_ty, tcx)
9798 } else {
9899 continue ;
@@ -103,20 +104,29 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
103104 let terminator = bb_data. terminator ( ) ;
104105 let TerminatorKind :: SwitchInt { targets, .. } = & terminator. kind else { bug ! ( ) } ;
105106
106- let mut reachable_count = 0 ;
107107 for ( index, ( val, _) ) in targets. iter ( ) . enumerate ( ) {
108- if allowed_variants. contains ( & val) {
109- reachable_count += 1 ;
110- } else {
108+ if !allowed_variants. remove ( & val) {
111109 removable_switchs. push ( ( bb, index) ) ;
112110 }
113111 }
114112
115- if reachable_count == allowed_variants. len ( ) {
113+ if allowed_variants. is_empty ( ) {
116114 removable_switchs. push ( ( bb, targets. iter ( ) . count ( ) ) ) ;
115+ } else if allowed_variants. len ( ) == 1 {
116+ #[ allow( rustc:: potential_query_instability) ]
117+ let last_variant = * allowed_variants. iter ( ) . next ( ) . unwrap ( ) ;
118+ otherwise_is_last_variant_switchs. push ( ( bb, last_variant) ) ;
117119 }
118120 }
119121
122+ for ( bb, last_variant) in otherwise_is_last_variant_switchs {
123+ let bb_data = & mut body. basic_blocks . as_mut ( ) [ bb] ;
124+ let terminator = bb_data. terminator_mut ( ) ;
125+ let TerminatorKind :: SwitchInt { targets, .. } = & mut terminator. kind else { bug ! ( ) } ;
126+ targets. add_target ( last_variant, targets. otherwise ( ) ) ;
127+ removable_switchs. push ( ( bb, targets. iter ( ) . count ( ) ) ) ;
128+ }
129+
120130 if removable_switchs. is_empty ( ) {
121131 return ;
122132 }
0 commit comments