Skip to content

Commit d1519b0

Browse files
authored
Unrolled build for rust-lang#121750
Rollup merge of rust-lang#121750 - Nadrieril:switchkind-if, r=matthewjasper match lowering: Separate the `bool` case from other integers in `TestKind` `TestKind::SwitchInt` had a special case for `bool` essentially everywhere it's used, so I made `TestKind::If` to handle the bool case on its own. r? `@matthewjasper`
2 parents e612d07 + d6332ae commit d1519b0

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
@@ -1097,21 +1097,18 @@ enum TestKind<'tcx> {
10971097
variants: BitSet<VariantIdx>,
10981098
},
10991099

1100-
/// Test what value an integer, `bool`, or `char` has.
1100+
/// Test what value an integer or `char` has.
11011101
SwitchInt {
1102-
/// The type of the value that we're testing.
1103-
switch_ty: Ty<'tcx>,
11041102
/// The (ordered) set of values that we test for.
11051103
///
1106-
/// For integers and `char`s we create a branch to each of the values in
1107-
/// `options`, as well as an "otherwise" branch for all other values, even
1108-
/// in the (rare) case that `options` is exhaustive.
1109-
///
1110-
/// For `bool` we always generate two edges, one for `true` and one for
1111-
/// `false`.
1104+
/// We create a branch to each of the values in `options`, as well as an "otherwise" branch
1105+
/// for all other values, even in the (rare) case that `options` is exhaustive.
11121106
options: FxIndexMap<Const<'tcx>, u128>,
11131107
},
11141108

1109+
/// Test what value a `bool` has.
1110+
If,
1111+
11151112
/// Test for equality with value, possibly after an unsizing coercion to
11161113
/// `ty`,
11171114
Eq {
@@ -1617,7 +1614,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
16171614
// a test like SwitchInt, we may want to add cases based on the candidates that are
16181615
// available
16191616
match test.kind {
1620-
TestKind::SwitchInt { switch_ty: _, ref mut options } => {
1617+
TestKind::SwitchInt { ref mut options } => {
16211618
for candidate in candidates.iter() {
16221619
if !self.add_cases_to_switch(&match_place, candidate, options) {
16231620
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,34 +182,29 @@ 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,
209196
};
210197
self.cfg.terminate(block, self.source_info(match_start_span), terminator);
211198
}
212199

200+
TestKind::If => {
201+
let [false_bb, true_bb] = *target_blocks else {
202+
bug!("`TestKind::If` should have two targets")
203+
};
204+
let terminator = TerminatorKind::if_(Operand::Copy(place), true_bb, false_bb);
205+
self.cfg.terminate(block, self.source_info(match_start_span), terminator);
206+
}
207+
213208
TestKind::Eq { value, ty } => {
214209
let tcx = self.tcx;
215210
let [success_block, fail_block] = *target_blocks else {
@@ -593,14 +588,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
593588
//
594589
// FIXME(#29623) we could use PatKind::Range to rule
595590
// things out here, in some cases.
596-
(TestKind::SwitchInt { switch_ty: _, options }, TestCase::Constant { value })
591+
(TestKind::SwitchInt { options }, TestCase::Constant { value })
597592
if is_switch_ty(match_pair.pattern.ty) =>
598593
{
599594
fully_matched = true;
600595
let index = options.get_index_of(value).unwrap();
601596
Some(index)
602597
}
603-
(TestKind::SwitchInt { switch_ty: _, options }, TestCase::Range(range)) => {
598+
(TestKind::SwitchInt { options }, TestCase::Range(range)) => {
604599
fully_matched = false;
605600
let not_contained =
606601
self.values_not_contained_in_range(&*range, options).unwrap_or(false);
@@ -616,6 +611,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
616611
None
617612
}
618613

614+
(&TestKind::If, TestCase::Constant { value }) => {
615+
fully_matched = true;
616+
let value = value.try_eval_bool(self.tcx, self.param_env).unwrap_or_else(|| {
617+
span_bug!(test.span, "expected boolean value but got {value:?}")
618+
});
619+
Some(value as usize)
620+
}
621+
(&TestKind::If, _) => {
622+
fully_matched = false;
623+
None
624+
}
625+
619626
(
620627
&TestKind::Len { len: test_len, op: BinOp::Eq },
621628
&TestCase::Slice { len, variable_length },
@@ -763,29 +770,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
763770
impl Test<'_> {
764771
pub(super) fn targets(&self) -> usize {
765772
match self.kind {
766-
TestKind::Eq { .. } | TestKind::Range(_) | TestKind::Len { .. } => 2,
773+
TestKind::Eq { .. } | TestKind::Range(_) | TestKind::Len { .. } | TestKind::If => 2,
767774
TestKind::Switch { adt_def, .. } => {
768775
// While the switch that we generate doesn't test for all
769776
// variants, we have a target for each variant and the
770777
// otherwise case, and we make sure that all of the cases not
771778
// specified have the same block.
772779
adt_def.variants().len() + 1
773780
}
774-
TestKind::SwitchInt { switch_ty, ref options, .. } => {
775-
if switch_ty.is_bool() {
776-
// `bool` is special cased in `perform_test` to always
777-
// branch to two blocks.
778-
2
779-
} else {
780-
options.len() + 1
781-
}
782-
}
781+
TestKind::SwitchInt { ref options } => options.len() + 1,
783782
}
784783
}
785784
}
786785

787786
fn is_switch_ty(ty: Ty<'_>) -> bool {
788-
ty.is_integral() || ty.is_char() || ty.is_bool()
787+
ty.is_integral() || ty.is_char()
789788
}
790789

791790
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)