@@ -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 {
@@ -589,14 +584,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
589584 //
590585 // FIXME(#29623) we could use PatKind::Range to rule
591586 // things out here, in some cases.
592- ( TestKind :: SwitchInt { switch_ty : _ , options } , TestCase :: Constant { value } )
587+ ( TestKind :: SwitchInt { options } , TestCase :: Constant { value } )
593588 if is_switch_ty ( match_pair. pattern . ty ) =>
594589 {
595590 fully_matched = true ;
596591 let index = options. get_index_of ( value) . unwrap ( ) ;
597592 Some ( index)
598593 }
599- ( TestKind :: SwitchInt { switch_ty : _ , options } , TestCase :: Range ( range) ) => {
594+ ( TestKind :: SwitchInt { options } , TestCase :: Range ( range) ) => {
600595 fully_matched = false ;
601596 let not_contained =
602597 self . values_not_contained_in_range ( & * range, options) . unwrap_or ( false ) ;
@@ -608,6 +603,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
608603 } )
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 } ,
@@ -746,29 +753,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
746753impl Test < ' _ > {
747754 pub ( super ) fn targets ( & self ) -> usize {
748755 match self . kind {
749- TestKind :: Eq { .. } | TestKind :: Range ( _) | TestKind :: Len { .. } => 2 ,
756+ TestKind :: Eq { .. } | TestKind :: Range ( _) | TestKind :: Len { .. } | TestKind :: If => 2 ,
750757 TestKind :: Switch { adt_def, .. } => {
751758 // While the switch that we generate doesn't test for all
752759 // variants, we have a target for each variant and the
753760 // otherwise case, and we make sure that all of the cases not
754761 // specified have the same block.
755762 adt_def. variants ( ) . len ( ) + 1
756763 }
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 ,
766765 }
767766 }
768767}
769768
770769fn is_switch_ty ( ty : Ty < ' _ > ) -> bool {
771- ty. is_integral ( ) || ty. is_char ( ) || ty . is_bool ( )
770+ ty. is_integral ( ) || ty. is_char ( )
772771}
773772
774773fn trait_method < ' tcx > (
0 commit comments