@@ -10,17 +10,14 @@ use crate::build::matches::{Candidate, MatchPair, Test, TestBranch, TestCase, Te
1010use crate :: build:: Builder ;
1111use rustc_data_structures:: fx:: FxIndexMap ;
1212use rustc_hir:: { LangItem , RangeEnd } ;
13- use rustc_index:: bit_set:: BitSet ;
1413use rustc_middle:: mir:: * ;
15- use rustc_middle:: thir:: * ;
1614use rustc_middle:: ty:: util:: IntTypeExt ;
1715use rustc_middle:: ty:: GenericArg ;
1816use rustc_middle:: ty:: { self , adjustment:: PointerCoercion , Ty , TyCtxt } ;
1917use rustc_span:: def_id:: DefId ;
2018use rustc_span:: source_map:: Spanned ;
2119use rustc_span:: symbol:: { sym, Symbol } ;
2220use rustc_span:: { Span , DUMMY_SP } ;
23- use rustc_target:: abi:: VariantIdx ;
2421
2522use std:: cmp:: Ordering ;
2623
@@ -30,22 +27,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
3027 /// It is a bug to call this with a not-fully-simplified pattern.
3128 pub ( super ) fn test < ' pat > ( & mut self , match_pair : & MatchPair < ' pat , ' tcx > ) -> Test < ' tcx > {
3229 let kind = match match_pair. test_case {
33- TestCase :: Variant { adt_def, variant_index : _ } => {
34- TestKind :: Switch { adt_def, variants : BitSet :: new_empty ( adt_def. variants ( ) . len ( ) ) }
35- }
30+ TestCase :: Variant { adt_def, variant_index : _ } => TestKind :: Switch { adt_def } ,
3631
3732 TestCase :: Constant { .. } if match_pair. pattern . ty . is_bool ( ) => TestKind :: If ,
38-
39- TestCase :: Constant { .. } if is_switch_ty ( match_pair. pattern . ty ) => {
40- // For integers, we use a `SwitchInt` match, which allows
41- // us to handle more cases.
42- TestKind :: SwitchInt {
43- // these maps are empty to start; cases are
44- // added below in add_cases_to_switch
45- options : Default :: default ( ) ,
46- }
47- }
48-
33+ TestCase :: Constant { .. } if is_switch_ty ( match_pair. pattern . ty ) => TestKind :: SwitchInt ,
4934 TestCase :: Constant { value } => TestKind :: Eq { value, ty : match_pair. pattern . ty } ,
5035
5136 TestCase :: Range ( range) => {
@@ -70,57 +55,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7055 Test { span : match_pair. pattern . span , kind }
7156 }
7257
73- pub ( super ) fn add_cases_to_switch < ' pat > (
74- & mut self ,
75- test_place : & PlaceBuilder < ' tcx > ,
76- candidate : & Candidate < ' pat , ' tcx > ,
77- options : & mut FxIndexMap < Const < ' tcx > , u128 > ,
78- ) -> bool {
79- let Some ( match_pair) = candidate. match_pairs . iter ( ) . find ( |mp| mp. place == * test_place)
80- else {
81- return false ;
82- } ;
83-
84- match match_pair. test_case {
85- TestCase :: Constant { value } => {
86- options. entry ( value) . or_insert_with ( || value. eval_bits ( self . tcx , self . param_env ) ) ;
87- true
88- }
89- TestCase :: Variant { .. } => {
90- panic ! ( "you should have called add_variants_to_switch instead!" ) ;
91- }
92- TestCase :: Range ( ref range) => {
93- // Check that none of the switch values are in the range.
94- self . values_not_contained_in_range ( & * range, options) . unwrap_or ( false )
95- }
96- // don't know how to add these patterns to a switch
97- _ => false ,
98- }
99- }
100-
101- pub ( super ) fn add_variants_to_switch < ' pat > (
102- & mut self ,
103- test_place : & PlaceBuilder < ' tcx > ,
104- candidate : & Candidate < ' pat , ' tcx > ,
105- variants : & mut BitSet < VariantIdx > ,
106- ) -> bool {
107- let Some ( match_pair) = candidate. match_pairs . iter ( ) . find ( |mp| mp. place == * test_place)
108- else {
109- return false ;
110- } ;
111-
112- match match_pair. test_case {
113- TestCase :: Variant { variant_index, .. } => {
114- // We have a pattern testing for variant `variant_index`
115- // set the corresponding index to true
116- variants. insert ( variant_index) ;
117- true
118- }
119- // don't know how to add these patterns to a switch
120- _ => false ,
121- }
122- }
123-
12458 #[ instrument( skip( self , target_blocks, place_builder) , level = "debug" ) ]
12559 pub ( super ) fn perform_test (
12660 & mut self ,
@@ -139,33 +73,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
13973
14074 let source_info = self . source_info ( test. span ) ;
14175 match test. kind {
142- TestKind :: Switch { adt_def, ref variants } => {
143- // Variants is a BitVec of indexes into adt_def.variants.
144- let num_enum_variants = adt_def. variants ( ) . len ( ) ;
76+ TestKind :: Switch { adt_def } => {
14577 let otherwise_block = target_block ( TestBranch :: Failure ) ;
146- let tcx = self . tcx ;
14778 let switch_targets = SwitchTargets :: new (
148- adt_def. discriminants ( tcx) . filter_map ( |( idx, discr) | {
149- if variants. contains ( idx) {
150- debug_assert_ne ! (
151- target_block( TestBranch :: Variant ( idx) ) ,
152- otherwise_block,
153- "no candidates for tested discriminant: {discr:?}" ,
154- ) ;
155- Some ( ( discr. val , target_block ( TestBranch :: Variant ( idx) ) ) )
79+ adt_def. discriminants ( self . tcx ) . filter_map ( |( idx, discr) | {
80+ if let Some ( & block) = target_blocks. get ( & TestBranch :: Variant ( idx) ) {
81+ Some ( ( discr. val , block) )
15682 } else {
157- debug_assert_eq ! (
158- target_block( TestBranch :: Variant ( idx) ) ,
159- otherwise_block,
160- "found candidates for untested discriminant: {discr:?}" ,
161- ) ;
16283 None
16384 }
16485 } ) ,
16586 otherwise_block,
16687 ) ;
167- debug ! ( "num_enum_variants: {}, variants: {:?} " , num_enum_variants , variants) ;
168- let discr_ty = adt_def. repr ( ) . discr_type ( ) . to_ty ( tcx) ;
88+ debug ! ( "num_enum_variants: {}" , adt_def . variants( ) . len ( ) ) ;
89+ let discr_ty = adt_def. repr ( ) . discr_type ( ) . to_ty ( self . tcx ) ;
16990 let discr = self . temp ( discr_ty, test. span ) ;
17091 self . cfg . push_assign (
17192 block,
@@ -183,13 +104,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
183104 ) ;
184105 }
185106
186- TestKind :: SwitchInt { ref options } => {
107+ TestKind :: SwitchInt => {
187108 // The switch may be inexhaustive so we have a catch-all block
188109 let otherwise_block = target_block ( TestBranch :: Failure ) ;
189110 let switch_targets = SwitchTargets :: new (
190- options
191- . iter ( )
192- . map ( |( & val, & bits) | ( bits, target_block ( TestBranch :: Constant ( val, bits) ) ) ) ,
111+ target_blocks. iter ( ) . filter_map ( |( & branch, & block) | {
112+ if let TestBranch :: Constant ( _, bits) = branch {
113+ Some ( ( bits, block) )
114+ } else {
115+ None
116+ }
117+ } ) ,
193118 otherwise_block,
194119 ) ;
195120 let terminator = TerminatorKind :: SwitchInt {
@@ -548,11 +473,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
548473 /// that it *doesn't* apply. For now, we return false, indicate that the
549474 /// test does not apply to this candidate, but it might be we can get
550475 /// tighter match code if we do something a bit different.
551- pub ( super ) fn sort_candidate < ' pat > (
476+ pub ( super ) fn sort_candidate (
552477 & mut self ,
553478 test_place : & PlaceBuilder < ' tcx > ,
554479 test : & Test < ' tcx > ,
555- candidate : & mut Candidate < ' pat , ' tcx > ,
480+ candidate : & mut Candidate < ' _ , ' tcx > ,
481+ sorted_candidates : & FxIndexMap < TestBranch < ' tcx > , Vec < & mut Candidate < ' _ , ' tcx > > > ,
556482 ) -> Option < TestBranch < ' tcx > > {
557483 // Find the match_pair for this place (if any). At present,
558484 // afaik, there can be at most one. (In the future, if we
@@ -568,7 +494,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
568494 // If we are performing a variant switch, then this
569495 // informs variant patterns, but nothing else.
570496 (
571- & TestKind :: Switch { adt_def : tested_adt_def, .. } ,
497+ & TestKind :: Switch { adt_def : tested_adt_def } ,
572498 & TestCase :: Variant { adt_def, variant_index } ,
573499 ) => {
574500 assert_eq ! ( adt_def, tested_adt_def) ;
@@ -581,17 +507,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
581507 //
582508 // FIXME(#29623) we could use PatKind::Range to rule
583509 // things out here, in some cases.
584- ( TestKind :: SwitchInt { options } , & TestCase :: Constant { value } )
510+ ( TestKind :: SwitchInt , & TestCase :: Constant { value } )
585511 if is_switch_ty ( match_pair. pattern . ty ) =>
586512 {
587513 fully_matched = true ;
588- let bits = options . get ( & value) . unwrap ( ) ;
589- Some ( TestBranch :: Constant ( value, * bits) )
514+ let bits = value. eval_bits ( self . tcx , self . param_env ) ;
515+ Some ( TestBranch :: Constant ( value, bits) )
590516 }
591- ( TestKind :: SwitchInt { options } , TestCase :: Range ( range) ) => {
517+ ( TestKind :: SwitchInt , TestCase :: Range ( range) ) => {
592518 fully_matched = false ;
593519 let not_contained =
594- self . values_not_contained_in_range ( & * range, options) . unwrap_or ( false ) ;
520+ sorted_candidates. keys ( ) . filter_map ( |br| br. as_constant ( ) ) . copied ( ) . all (
521+ |val| matches ! ( range. contains( val, self . tcx, self . param_env) , Some ( false ) ) ,
522+ ) ;
595523
596524 not_contained. then ( || {
597525 // No switch values are contained in the pattern range,
@@ -732,20 +660,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
732660
733661 ret
734662 }
735-
736- fn values_not_contained_in_range (
737- & self ,
738- range : & PatRange < ' tcx > ,
739- options : & FxIndexMap < Const < ' tcx > , u128 > ,
740- ) -> Option < bool > {
741- for & val in options. keys ( ) {
742- if range. contains ( val, self . tcx , self . param_env ) ? {
743- return Some ( false ) ;
744- }
745- }
746-
747- Some ( true )
748- }
749663}
750664
751665fn is_switch_ty ( ty : Ty < ' _ > ) -> bool {
0 commit comments