@@ -34,12 +34,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
34
34
TestKind :: Switch { adt_def, variants : BitSet :: new_empty ( adt_def. variants ( ) . len ( ) ) }
35
35
}
36
36
37
+ TestCase :: Constant { .. } if match_pair. pattern . ty . is_bool ( ) => TestKind :: If ,
38
+
37
39
TestCase :: Constant { .. } if is_switch_ty ( match_pair. pattern . ty ) => {
38
40
// For integers, we use a `SwitchInt` match, which allows
39
41
// us to handle more cases.
40
42
TestKind :: SwitchInt {
41
- switch_ty : match_pair. pattern . ty ,
42
-
43
43
// these maps are empty to start; cases are
44
44
// added below in add_cases_to_switch
45
45
options : Default :: default ( ) ,
@@ -182,34 +182,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
182
182
) ;
183
183
}
184
184
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,
209
196
} ;
210
197
self . cfg . terminate ( block, self . source_info ( match_start_span) , terminator) ;
211
198
}
212
199
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
+
213
208
TestKind :: Eq { value, ty } => {
214
209
let tcx = self . tcx ;
215
210
let [ success_block, fail_block] = * target_blocks else {
@@ -589,14 +584,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
589
584
//
590
585
// FIXME(#29623) we could use PatKind::Range to rule
591
586
// things out here, in some cases.
592
- ( TestKind :: SwitchInt { switch_ty : _ , options } , TestCase :: Constant { value } )
587
+ ( TestKind :: SwitchInt { options } , TestCase :: Constant { value } )
593
588
if is_switch_ty ( match_pair. pattern . ty ) =>
594
589
{
595
590
fully_matched = true ;
596
591
let index = options. get_index_of ( value) . unwrap ( ) ;
597
592
Some ( index)
598
593
}
599
- ( TestKind :: SwitchInt { switch_ty : _ , options } , TestCase :: Range ( range) ) => {
594
+ ( TestKind :: SwitchInt { options } , TestCase :: Range ( range) ) => {
600
595
fully_matched = false ;
601
596
let not_contained =
602
597
self . values_not_contained_in_range ( & * range, options) . unwrap_or ( false ) ;
@@ -608,6 +603,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
608
603
} )
609
604
}
610
605
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
+
611
618
(
612
619
& TestKind :: Len { len : test_len, op : BinOp :: Eq } ,
613
620
& TestCase :: Slice { len, variable_length } ,
@@ -746,29 +753,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
746
753
impl Test < ' _ > {
747
754
pub ( super ) fn targets ( & self ) -> usize {
748
755
match self . kind {
749
- TestKind :: Eq { .. } | TestKind :: Range ( _) | TestKind :: Len { .. } => 2 ,
756
+ TestKind :: Eq { .. } | TestKind :: Range ( _) | TestKind :: Len { .. } | TestKind :: If => 2 ,
750
757
TestKind :: Switch { adt_def, .. } => {
751
758
// While the switch that we generate doesn't test for all
752
759
// variants, we have a target for each variant and the
753
760
// otherwise case, and we make sure that all of the cases not
754
761
// specified have the same block.
755
762
adt_def. variants ( ) . len ( ) + 1
756
763
}
757
- TestKind :: SwitchInt { switch_ty, ref options, .. } => {
758
- if switch_ty. is_bool ( ) {
759
- // `bool` is special cased in `perform_test` to always
760
- // branch to two blocks.
761
- 2
762
- } else {
763
- options. len ( ) + 1
764
- }
765
- }
764
+ TestKind :: SwitchInt { ref options } => options. len ( ) + 1 ,
766
765
}
767
766
}
768
767
}
769
768
770
769
fn is_switch_ty ( ty : Ty < ' _ > ) -> bool {
771
- ty. is_integral ( ) || ty. is_char ( ) || ty . is_bool ( )
770
+ ty. is_integral ( ) || ty. is_char ( )
772
771
}
773
772
774
773
fn trait_method < ' tcx > (
0 commit comments