Skip to content

Commit d6332ae

Browse files
committed
Separate the bool case from other integers in TestKind
1 parent ef32456 commit d6332ae

4 files changed

+59
-65
lines changed

compiler/rustc_mir_build/src/build/matches/mod.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -1091,21 +1091,18 @@ enum TestKind<'tcx> {
10911091
variants: BitSet<VariantIdx>,
10921092
},
10931093

1094-
/// Test what value an integer, `bool`, or `char` has.
1094+
/// Test what value an integer or `char` has.
10951095
SwitchInt {
1096-
/// The type of the value that we're testing.
1097-
switch_ty: Ty<'tcx>,
10981096
/// The (ordered) set of values that we test for.
10991097
///
1100-
/// For integers and `char`s we create a branch to each of the values in
1101-
/// `options`, as well as an "otherwise" branch for all other values, even
1102-
/// in the (rare) case that `options` is exhaustive.
1103-
///
1104-
/// For `bool` we always generate two edges, one for `true` and one for
1105-
/// `false`.
1098+
/// We create a branch to each of the values in `options`, as well as an "otherwise" branch
1099+
/// for all other values, even in the (rare) case that `options` is exhaustive.
11061100
options: FxIndexMap<Const<'tcx>, u128>,
11071101
},
11081102

1103+
/// Test what value a `bool` has.
1104+
If,
1105+
11091106
/// Test for equality with value, possibly after an unsizing coercion to
11101107
/// `ty`,
11111108
Eq {
@@ -1611,7 +1608,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
16111608
// a test like SwitchInt, we may want to add cases based on the candidates that are
16121609
// available
16131610
match test.kind {
1614-
TestKind::SwitchInt { switch_ty: _, ref mut options } => {
1611+
TestKind::SwitchInt { ref mut options } => {
16151612
for candidate in candidates.iter() {
16161613
if !self.add_cases_to_switch(&match_place, candidate, options) {
16171614
break;

compiler/rustc_mir_build/src/build/matches/test.rs

+38-39
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
3434
TestKind::Switch { adt_def, variants: BitSet::new_empty(adt_def.variants().len()) }
3535
}
3636

37+
TestCase::Constant { .. } if match_pair.pattern.ty.is_bool() => TestKind::If,
38+
3739
TestCase::Constant { .. } if is_switch_ty(match_pair.pattern.ty) => {
3840
// For integers, we use a `SwitchInt` match, which allows
3941
// us to handle more cases.
4042
TestKind::SwitchInt {
41-
switch_ty: match_pair.pattern.ty,
42-
4343
// these maps are empty to start; cases are
4444
// added below in add_cases_to_switch
4545
options: Default::default(),
@@ -182,31 +182,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
182182
);
183183
}
184184

185-
TestKind::SwitchInt { switch_ty, ref options } => {
186-
let terminator = if *switch_ty.kind() == ty::Bool {
187-
assert!(!options.is_empty() && options.len() <= 2);
188-
let [first_bb, second_bb] = *target_blocks else {
189-
bug!("`TestKind::SwitchInt` on `bool` should have two targets")
190-
};
191-
let (true_bb, false_bb) = match options[0] {
192-
1 => (first_bb, second_bb),
193-
0 => (second_bb, first_bb),
194-
v => span_bug!(test.span, "expected boolean value but got {:?}", v),
195-
};
196-
TerminatorKind::if_(Operand::Copy(place), true_bb, false_bb)
197-
} else {
198-
// The switch may be inexhaustive so we have a catch all block
199-
debug_assert_eq!(options.len() + 1, target_blocks.len());
200-
let otherwise_block = *target_blocks.last().unwrap();
201-
let switch_targets = SwitchTargets::new(
202-
options.values().copied().zip(target_blocks),
203-
otherwise_block,
204-
);
205-
TerminatorKind::SwitchInt {
206-
discr: Operand::Copy(place),
207-
targets: switch_targets,
208-
}
185+
TestKind::SwitchInt { ref options } => {
186+
// The switch may be inexhaustive so we have a catch-all block
187+
debug_assert_eq!(options.len() + 1, target_blocks.len());
188+
let otherwise_block = *target_blocks.last().unwrap();
189+
let switch_targets = SwitchTargets::new(
190+
options.values().copied().zip(target_blocks),
191+
otherwise_block,
192+
);
193+
let terminator = TerminatorKind::SwitchInt {
194+
discr: Operand::Copy(place),
195+
targets: switch_targets,
196+
};
197+
self.cfg.terminate(block, self.source_info(match_start_span), terminator);
198+
}
199+
200+
TestKind::If => {
201+
let [false_bb, true_bb] = *target_blocks else {
202+
bug!("`TestKind::If` should have two targets")
209203
};
204+
let terminator = TerminatorKind::if_(Operand::Copy(place), true_bb, false_bb);
210205
self.cfg.terminate(block, self.source_info(match_start_span), terminator);
211206
}
212207

@@ -585,14 +580,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
585580
//
586581
// FIXME(#29623) we could use PatKind::Range to rule
587582
// things out here, in some cases.
588-
(TestKind::SwitchInt { switch_ty: _, options }, TestCase::Constant { value })
583+
(TestKind::SwitchInt { options }, TestCase::Constant { value })
589584
if is_switch_ty(match_pair.pattern.ty) =>
590585
{
591586
fully_matched = true;
592587
let index = options.get_index_of(value).unwrap();
593588
Some(index)
594589
}
595-
(TestKind::SwitchInt { switch_ty: _, options }, TestCase::Range(range)) => {
590+
(TestKind::SwitchInt { options }, TestCase::Range(range)) => {
596591
fully_matched = false;
597592
let not_contained =
598593
self.values_not_contained_in_range(&*range, options).unwrap_or(false);
@@ -608,6 +603,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
608603
None
609604
}
610605

606+
(&TestKind::If, TestCase::Constant { value }) => {
607+
fully_matched = true;
608+
let value = value.try_eval_bool(self.tcx, self.param_env).unwrap_or_else(|| {
609+
span_bug!(test.span, "expected boolean value but got {value:?}")
610+
});
611+
Some(value as usize)
612+
}
613+
(&TestKind::If, _) => {
614+
fully_matched = false;
615+
None
616+
}
617+
611618
(
612619
&TestKind::Len { len: test_len, op: BinOp::Eq },
613620
&TestCase::Slice { len, variable_length },
@@ -755,29 +762,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
755762
impl Test<'_> {
756763
pub(super) fn targets(&self) -> usize {
757764
match self.kind {
758-
TestKind::Eq { .. } | TestKind::Range(_) | TestKind::Len { .. } => 2,
765+
TestKind::Eq { .. } | TestKind::Range(_) | TestKind::Len { .. } | TestKind::If => 2,
759766
TestKind::Switch { adt_def, .. } => {
760767
// While the switch that we generate doesn't test for all
761768
// variants, we have a target for each variant and the
762769
// otherwise case, and we make sure that all of the cases not
763770
// specified have the same block.
764771
adt_def.variants().len() + 1
765772
}
766-
TestKind::SwitchInt { switch_ty, ref options, .. } => {
767-
if switch_ty.is_bool() {
768-
// `bool` is special cased in `perform_test` to always
769-
// branch to two blocks.
770-
2
771-
} else {
772-
options.len() + 1
773-
}
774-
}
773+
TestKind::SwitchInt { ref options } => options.len() + 1,
775774
}
776775
}
777776
}
778777

779778
fn is_switch_ty(ty: Ty<'_>) -> bool {
780-
ty.is_integral() || ty.is_char() || ty.is_bool()
779+
ty.is_integral() || ty.is_char()
781780
}
782781

783782
fn trait_method<'tcx>(

tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff

+7-8
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,11 @@
4242
}
4343

4444
bb2: {
45-
- switchInt((_2.0: bool)) -> [0: bb4, otherwise: bb3];
45+
- switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb4];
4646
+ switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb17];
4747
}
4848

4949
bb3: {
50-
- falseEdge -> [real: bb20, imaginary: bb4];
51-
- }
52-
-
53-
- bb4: {
5450
StorageLive(_15);
5551
_15 = (_2.1: bool);
5652
StorageLive(_16);
@@ -59,16 +55,19 @@
5955
+ goto -> bb16;
6056
}
6157

58+
bb4: {
59+
- falseEdge -> [real: bb20, imaginary: bb3];
60+
- }
61+
-
6262
- bb5: {
63-
- falseEdge -> [real: bb13, imaginary: bb3];
63+
- falseEdge -> [real: bb13, imaginary: bb4];
6464
- }
6565
-
6666
- bb6: {
6767
- falseEdge -> [real: bb8, imaginary: bb5];
6868
- }
6969
-
7070
- bb7: {
71-
+ bb4: {
7271
_0 = const 1_i32;
7372
- drop(_7) -> [return: bb18, unwind: bb25];
7473
+ drop(_7) -> [return: bb15, unwind: bb22];
@@ -184,7 +183,7 @@
184183
StorageDead(_12);
185184
StorageDead(_8);
186185
StorageDead(_6);
187-
- falseEdge -> [real: bb2, imaginary: bb3];
186+
- falseEdge -> [real: bb2, imaginary: bb4];
188187
+ goto -> bb2;
189188
}
190189

tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff

+7-8
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,11 @@
4242
}
4343

4444
bb2: {
45-
- switchInt((_2.0: bool)) -> [0: bb4, otherwise: bb3];
45+
- switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb4];
4646
+ switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb17];
4747
}
4848

4949
bb3: {
50-
- falseEdge -> [real: bb20, imaginary: bb4];
51-
- }
52-
-
53-
- bb4: {
5450
StorageLive(_15);
5551
_15 = (_2.1: bool);
5652
StorageLive(_16);
@@ -59,16 +55,19 @@
5955
+ goto -> bb16;
6056
}
6157

58+
bb4: {
59+
- falseEdge -> [real: bb20, imaginary: bb3];
60+
- }
61+
-
6262
- bb5: {
63-
- falseEdge -> [real: bb13, imaginary: bb3];
63+
- falseEdge -> [real: bb13, imaginary: bb4];
6464
- }
6565
-
6666
- bb6: {
6767
- falseEdge -> [real: bb8, imaginary: bb5];
6868
- }
6969
-
7070
- bb7: {
71-
+ bb4: {
7271
_0 = const 1_i32;
7372
- drop(_7) -> [return: bb18, unwind: bb25];
7473
+ drop(_7) -> [return: bb15, unwind: bb22];
@@ -184,7 +183,7 @@
184183
StorageDead(_12);
185184
StorageDead(_8);
186185
StorageDead(_6);
187-
- falseEdge -> [real: bb2, imaginary: bb3];
186+
- falseEdge -> [real: bb2, imaginary: bb4];
188187
+ goto -> bb2;
189188
}
190189

0 commit comments

Comments
 (0)