@@ -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