@@ -78,6 +78,7 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
78
78
trace ! ( "UninhabitedEnumBranching starting for {:?}" , body. source) ;
79
79
80
80
let mut removable_switchs = Vec :: new ( ) ;
81
+ let mut otherwise_is_last_variant_switchs = Vec :: new ( ) ;
81
82
82
83
for ( bb, bb_data) in body. basic_blocks . iter_enumerated ( ) {
83
84
trace ! ( "processing block {:?}" , bb) ;
@@ -92,7 +93,7 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
92
93
tcx. param_env_reveal_all_normalized ( body. source . def_id ( ) ) . and ( discriminant_ty) ,
93
94
) ;
94
95
95
- let allowed_variants = if let Ok ( layout) = layout {
96
+ let mut allowed_variants = if let Ok ( layout) = layout {
96
97
variant_discriminants ( & layout, discriminant_ty, tcx)
97
98
} else {
98
99
continue ;
@@ -103,20 +104,29 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
103
104
let terminator = bb_data. terminator ( ) ;
104
105
let TerminatorKind :: SwitchInt { targets, .. } = & terminator. kind else { bug ! ( ) } ;
105
106
106
- let mut reachable_count = 0 ;
107
107
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) {
111
109
removable_switchs. push ( ( bb, index) ) ;
112
110
}
113
111
}
114
112
115
- if reachable_count == allowed_variants. len ( ) {
113
+ if allowed_variants. is_empty ( ) {
116
114
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) ) ;
117
119
}
118
120
}
119
121
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
+
120
130
if removable_switchs. is_empty ( ) {
121
131
return ;
122
132
}
0 commit comments