@@ -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,31 +182,26 @@ 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,
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" )
209
203
} ;
204
+ let terminator = TerminatorKind :: if_ ( Operand :: Copy ( place) , true_bb, false_bb) ;
210
205
self . cfg . terminate ( block, self . source_info ( match_start_span) , terminator) ;
211
206
}
212
207
@@ -585,14 +580,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
585
580
//
586
581
// FIXME(#29623) we could use PatKind::Range to rule
587
582
// things out here, in some cases.
588
- ( TestKind :: SwitchInt { switch_ty : _ , options } , TestCase :: Constant { value } )
583
+ ( TestKind :: SwitchInt { options } , TestCase :: Constant { value } )
589
584
if is_switch_ty ( match_pair. pattern . ty ) =>
590
585
{
591
586
fully_matched = true ;
592
587
let index = options. get_index_of ( value) . unwrap ( ) ;
593
588
Some ( index)
594
589
}
595
- ( TestKind :: SwitchInt { switch_ty : _ , options } , TestCase :: Range ( range) ) => {
590
+ ( TestKind :: SwitchInt { options } , TestCase :: Range ( range) ) => {
596
591
fully_matched = false ;
597
592
let not_contained =
598
593
self . values_not_contained_in_range ( & * range, options) . unwrap_or ( false ) ;
@@ -608,6 +603,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
608
603
None
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 } ,
@@ -755,29 +762,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
755
762
impl Test < ' _ > {
756
763
pub ( super ) fn targets ( & self ) -> usize {
757
764
match self . kind {
758
- TestKind :: Eq { .. } | TestKind :: Range ( _) | TestKind :: Len { .. } => 2 ,
765
+ TestKind :: Eq { .. } | TestKind :: Range ( _) | TestKind :: Len { .. } | TestKind :: If => 2 ,
759
766
TestKind :: Switch { adt_def, .. } => {
760
767
// While the switch that we generate doesn't test for all
761
768
// variants, we have a target for each variant and the
762
769
// otherwise case, and we make sure that all of the cases not
763
770
// specified have the same block.
764
771
adt_def. variants ( ) . len ( ) + 1
765
772
}
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 ,
775
774
}
776
775
}
777
776
}
778
777
779
778
fn is_switch_ty ( ty : Ty < ' _ > ) -> bool {
780
- ty. is_integral ( ) || ty. is_char ( ) || ty . is_bool ( )
779
+ ty. is_integral ( ) || ty. is_char ( )
781
780
}
782
781
783
782
fn trait_method < ' tcx > (
0 commit comments