@@ -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 {
@@ -593,14 +588,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
593
588
//
594
589
// FIXME(#29623) we could use PatKind::Range to rule
595
590
// things out here, in some cases.
596
- ( TestKind :: SwitchInt { switch_ty : _ , options } , TestCase :: Constant { value } )
591
+ ( TestKind :: SwitchInt { options } , TestCase :: Constant { value } )
597
592
if is_switch_ty ( match_pair. pattern . ty ) =>
598
593
{
599
594
fully_matched = true ;
600
595
let index = options. get_index_of ( value) . unwrap ( ) ;
601
596
Some ( index)
602
597
}
603
- ( TestKind :: SwitchInt { switch_ty : _ , options } , TestCase :: Range ( range) ) => {
598
+ ( TestKind :: SwitchInt { options } , TestCase :: Range ( range) ) => {
604
599
fully_matched = false ;
605
600
let not_contained =
606
601
self . values_not_contained_in_range ( & * range, options) . unwrap_or ( false ) ;
@@ -616,6 +611,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
616
611
None
617
612
}
618
613
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
+
619
626
(
620
627
& TestKind :: Len { len : test_len, op : BinOp :: Eq } ,
621
628
& TestCase :: Slice { len, variable_length } ,
@@ -763,29 +770,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
763
770
impl Test < ' _ > {
764
771
pub ( super ) fn targets ( & self ) -> usize {
765
772
match self . kind {
766
- TestKind :: Eq { .. } | TestKind :: Range ( _) | TestKind :: Len { .. } => 2 ,
773
+ TestKind :: Eq { .. } | TestKind :: Range ( _) | TestKind :: Len { .. } | TestKind :: If => 2 ,
767
774
TestKind :: Switch { adt_def, .. } => {
768
775
// While the switch that we generate doesn't test for all
769
776
// variants, we have a target for each variant and the
770
777
// otherwise case, and we make sure that all of the cases not
771
778
// specified have the same block.
772
779
adt_def. variants ( ) . len ( ) + 1
773
780
}
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 ,
783
782
}
784
783
}
785
784
}
786
785
787
786
fn is_switch_ty ( ty : Ty < ' _ > ) -> bool {
788
- ty. is_integral ( ) || ty. is_char ( ) || ty . is_bool ( )
787
+ ty. is_integral ( ) || ty. is_char ( )
789
788
}
790
789
791
790
fn trait_method < ' tcx > (
0 commit comments