@@ -168,7 +168,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
168
168
block : BasicBlock ,
169
169
place : & Place < ' tcx > ,
170
170
test : & Test < ' tcx > ,
171
- target_blocks : Vec < BasicBlock > ,
171
+ make_target_blocks : impl FnOnce ( & mut Self ) -> Vec < BasicBlock > ,
172
172
) {
173
173
debug ! ( "perform_test({:?}, {:?}: {:?}, {:?})" ,
174
174
block,
@@ -179,6 +179,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
179
179
let source_info = self . source_info ( test. span ) ;
180
180
match test. kind {
181
181
TestKind :: Switch { adt_def, ref variants } => {
182
+ let target_blocks = make_target_blocks ( self ) ;
182
183
// Variants is a BitVec of indexes into adt_def.variants.
183
184
let num_enum_variants = adt_def. variants . len ( ) ;
184
185
let used_variants = variants. count ( ) ;
@@ -223,6 +224,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
223
224
}
224
225
225
226
TestKind :: SwitchInt { switch_ty, ref options, indices : _ } => {
227
+ let target_blocks = make_target_blocks ( self ) ;
226
228
let terminator = if switch_ty. sty == ty:: Bool {
227
229
assert ! ( options. len( ) > 0 && options. len( ) <= 2 ) ;
228
230
if let [ first_bb, second_bb] = * target_blocks {
@@ -254,38 +256,38 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
254
256
}
255
257
256
258
TestKind :: Eq { value, ty } => {
257
- if let [ success, fail] = * target_blocks {
258
- if !ty. is_scalar ( ) {
259
- // Use `PartialEq::eq` instead of `BinOp::Eq`
260
- // (the binop can only handle primitives)
261
- self . non_scalar_compare (
262
- block,
263
- success,
264
- fail,
265
- source_info,
266
- value,
267
- place,
268
- ty,
269
- ) ;
270
- } else {
259
+ if !ty. is_scalar ( ) {
260
+ // Use `PartialEq::eq` instead of `BinOp::Eq`
261
+ // (the binop can only handle primitives)
262
+ self . non_scalar_compare (
263
+ block,
264
+ make_target_blocks,
265
+ source_info,
266
+ value,
267
+ place,
268
+ ty,
269
+ ) ;
270
+ } else {
271
+ if let [ success, fail] = * make_target_blocks ( self ) {
271
272
let val = Operand :: Copy ( place. clone ( ) ) ;
272
273
let expect = self . literal_operand ( test. span , ty, value) ;
273
274
self . compare ( block, success, fail, source_info, BinOp :: Eq , expect, val) ;
275
+ } else {
276
+ bug ! ( "`TestKind::Eq` should have two target blocks" ) ;
274
277
}
275
- } else {
276
- bug ! ( "`TestKind::Eq` should have two target blocks" )
277
- } ;
278
+ }
278
279
}
279
280
280
281
TestKind :: Range ( PatternRange { ref lo, ref hi, ty, ref end } ) => {
282
+ let lower_bound_success = self . cfg . start_new_block ( ) ;
283
+ let target_blocks = make_target_blocks ( self ) ;
284
+
281
285
// Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons.
282
286
let lo = self . literal_operand ( test. span , ty, lo) ;
283
287
let hi = self . literal_operand ( test. span , ty, hi) ;
284
288
let val = Operand :: Copy ( place. clone ( ) ) ;
285
289
286
290
if let [ success, fail] = * target_blocks {
287
- let lower_bound_success = self . cfg . start_new_block ( ) ;
288
-
289
291
self . compare (
290
292
block,
291
293
lower_bound_success,
@@ -306,6 +308,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
306
308
}
307
309
308
310
TestKind :: Len { len, op } => {
311
+ let target_blocks = make_target_blocks ( self ) ;
312
+
309
313
let usize_ty = self . hir . usize_ty ( ) ;
310
314
let actual = self . temp ( usize_ty, test. span ) ;
311
315
@@ -374,8 +378,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
374
378
fn non_scalar_compare (
375
379
& mut self ,
376
380
block : BasicBlock ,
377
- success_block : BasicBlock ,
378
- fail_block : BasicBlock ,
381
+ make_target_blocks : impl FnOnce ( & mut Self ) -> Vec < BasicBlock > ,
379
382
source_info : SourceInfo ,
380
383
value : & ' tcx ty:: Const < ' tcx > ,
381
384
place : & Place < ' tcx > ,
@@ -461,17 +464,21 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
461
464
from_hir_call : false ,
462
465
} ) ;
463
466
464
- // check the result
465
- self . cfg . terminate (
466
- eq_block,
467
- source_info,
468
- TerminatorKind :: if_ (
469
- self . hir . tcx ( ) ,
470
- Operand :: Move ( eq_result) ,
471
- success_block,
472
- fail_block,
473
- ) ,
474
- ) ;
467
+ if let [ success_block, fail_block] = * make_target_blocks ( self ) {
468
+ // check the result
469
+ self . cfg . terminate (
470
+ eq_block,
471
+ source_info,
472
+ TerminatorKind :: if_ (
473
+ self . hir . tcx ( ) ,
474
+ Operand :: Move ( eq_result) ,
475
+ success_block,
476
+ fail_block,
477
+ ) ,
478
+ ) ;
479
+ } else {
480
+ bug ! ( "`TestKind::Eq` should have two target blocks" )
481
+ }
475
482
}
476
483
477
484
/// Given that we are performing `test` against `test_place`, this job
0 commit comments