@@ -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,31 +182,26 @@ 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,
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" )
209203 } ;
204+ let terminator = TerminatorKind :: if_ ( Operand :: Copy ( place) , true_bb, false_bb) ;
210205 self . cfg . terminate ( block, self . source_info ( match_start_span) , terminator) ;
211206 }
212207
@@ -585,14 +580,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
585580 //
586581 // FIXME(#29623) we could use PatKind::Range to rule
587582 // things out here, in some cases.
588- ( TestKind :: SwitchInt { switch_ty : _ , options } , TestCase :: Constant { value } )
583+ ( TestKind :: SwitchInt { options } , TestCase :: Constant { value } )
589584 if is_switch_ty ( match_pair. pattern . ty ) =>
590585 {
591586 fully_matched = true ;
592587 let index = options. get_index_of ( value) . unwrap ( ) ;
593588 Some ( index)
594589 }
595- ( TestKind :: SwitchInt { switch_ty : _ , options } , TestCase :: Range ( range) ) => {
590+ ( TestKind :: SwitchInt { options } , TestCase :: Range ( range) ) => {
596591 fully_matched = false ;
597592 let not_contained =
598593 self . values_not_contained_in_range ( & * range, options) . unwrap_or ( false ) ;
@@ -608,6 +603,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
608603 None
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 } ,
@@ -755,29 +762,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
755762impl Test < ' _ > {
756763 pub ( super ) fn targets ( & self ) -> usize {
757764 match self . kind {
758- TestKind :: Eq { .. } | TestKind :: Range ( _) | TestKind :: Len { .. } => 2 ,
765+ TestKind :: Eq { .. } | TestKind :: Range ( _) | TestKind :: Len { .. } | TestKind :: If => 2 ,
759766 TestKind :: Switch { adt_def, .. } => {
760767 // While the switch that we generate doesn't test for all
761768 // variants, we have a target for each variant and the
762769 // otherwise case, and we make sure that all of the cases not
763770 // specified have the same block.
764771 adt_def. variants ( ) . len ( ) + 1
765772 }
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 ,
775774 }
776775 }
777776}
778777
779778fn is_switch_ty ( ty : Ty < ' _ > ) -> bool {
780- ty. is_integral ( ) || ty. is_char ( ) || ty . is_bool ( )
779+ ty. is_integral ( ) || ty. is_char ( )
781780}
782781
783782fn trait_method < ' tcx > (
0 commit comments