@@ -7,6 +7,7 @@ use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
7
7
use rustc_middle:: ty:: { ParamEnv , ScalarInt , Ty , TyCtxt } ;
8
8
use rustc_target:: abi:: Integer ;
9
9
use rustc_type_ir:: TyKind :: * ;
10
+ use tracing:: instrument;
10
11
11
12
use super :: simplify:: simplify_cfg;
12
13
@@ -57,7 +58,7 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
57
58
}
58
59
59
60
trait SimplifyMatch < ' tcx > {
60
- /// Simplifies a match statement, returning true if the simplification succeeds, false
61
+ /// Simplifies a match statement, returning `Some` if the simplification succeeds, `None`
61
62
/// otherwise. Generic code is written here, and we generally don't need a custom
62
63
/// implementation.
63
64
fn simplify (
@@ -156,6 +157,7 @@ struct SimplifyToIf;
156
157
/// }
157
158
/// ```
158
159
impl < ' tcx > SimplifyMatch < ' tcx > for SimplifyToIf {
160
+ #[ instrument( level = "debug" , skip( self , tcx) , ret) ]
159
161
fn can_simplify (
160
162
& mut self ,
161
163
tcx : TyCtxt < ' tcx > ,
@@ -164,12 +166,15 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf {
164
166
bbs : & IndexSlice < BasicBlock , BasicBlockData < ' tcx > > ,
165
167
_discr_ty : Ty < ' tcx > ,
166
168
) -> Option < ( ) > {
167
- if targets. iter ( ) . len ( ) != 1 {
168
- return None ;
169
- }
169
+ let ( first, second) = match targets. all_targets ( ) {
170
+ & [ first, otherwise] => ( first, otherwise) ,
171
+ & [ first, second, otherwise] if bbs[ otherwise] . is_empty_unreachable ( ) => ( first, second) ,
172
+ _ => {
173
+ return None ;
174
+ }
175
+ } ;
176
+
170
177
// We require that the possible target blocks all be distinct.
171
- let ( _, first) = targets. iter ( ) . next ( ) . unwrap ( ) ;
172
- let second = targets. otherwise ( ) ;
173
178
if first == second {
174
179
return None ;
175
180
}
@@ -218,8 +223,14 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf {
218
223
discr_local : Local ,
219
224
discr_ty : Ty < ' tcx > ,
220
225
) {
221
- let ( val, first) = targets. iter ( ) . next ( ) . unwrap ( ) ;
222
- let second = targets. otherwise ( ) ;
226
+ let ( ( val, first) , second) = match ( targets. all_targets ( ) , targets. all_values ( ) ) {
227
+ ( & [ first, otherwise] , & [ val] ) => ( ( val, first) , otherwise) ,
228
+ ( & [ first, second, otherwise] , & [ val, _] ) if bbs[ otherwise] . is_empty_unreachable ( ) => {
229
+ ( ( val, first) , second)
230
+ }
231
+ _ => unreachable ! ( ) ,
232
+ } ;
233
+
223
234
// We already checked that first and second are different blocks,
224
235
// and bb_idx has a different terminator from both of them.
225
236
let first = & bbs[ first] ;
@@ -294,7 +305,7 @@ struct SimplifyToExp {
294
305
transform_kinds : Vec < TransformKind > ,
295
306
}
296
307
297
- #[ derive( Clone , Copy ) ]
308
+ #[ derive( Clone , Copy , Debug ) ]
298
309
enum ExpectedTransformKind < ' a , ' tcx > {
299
310
/// Identical statements.
300
311
Same ( & ' a StatementKind < ' tcx > ) ,
@@ -359,6 +370,7 @@ impl From<ExpectedTransformKind<'_, '_>> for TransformKind {
359
370
/// }
360
371
/// ```
361
372
impl < ' tcx > SimplifyMatch < ' tcx > for SimplifyToExp {
373
+ #[ instrument( level = "debug" , skip( self , tcx) , ret) ]
362
374
fn can_simplify (
363
375
& mut self ,
364
376
tcx : TyCtxt < ' tcx > ,
0 commit comments