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