@@ -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> {
763770impl 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
787786fn 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
791790fn trait_method < ' tcx > (
0 commit comments