@@ -10,17 +10,14 @@ use crate::build::matches::{Candidate, MatchPair, Test, TestBranch, TestCase, Te
10
10
use crate :: build:: Builder ;
11
11
use rustc_data_structures:: fx:: FxIndexMap ;
12
12
use rustc_hir:: { LangItem , RangeEnd } ;
13
- use rustc_index:: bit_set:: BitSet ;
14
13
use rustc_middle:: mir:: * ;
15
- use rustc_middle:: thir:: * ;
16
14
use rustc_middle:: ty:: util:: IntTypeExt ;
17
15
use rustc_middle:: ty:: GenericArg ;
18
16
use rustc_middle:: ty:: { self , adjustment:: PointerCoercion , Ty , TyCtxt } ;
19
17
use rustc_span:: def_id:: DefId ;
20
18
use rustc_span:: source_map:: Spanned ;
21
19
use rustc_span:: symbol:: { sym, Symbol } ;
22
20
use rustc_span:: { Span , DUMMY_SP } ;
23
- use rustc_target:: abi:: VariantIdx ;
24
21
25
22
use std:: cmp:: Ordering ;
26
23
@@ -30,22 +27,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
30
27
/// It is a bug to call this with a not-fully-simplified pattern.
31
28
pub ( super ) fn test < ' pat > ( & mut self , match_pair : & MatchPair < ' pat , ' tcx > ) -> Test < ' tcx > {
32
29
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 } ,
36
31
37
32
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 ,
49
34
TestCase :: Constant { value } => TestKind :: Eq { value, ty : match_pair. pattern . ty } ,
50
35
51
36
TestCase :: Range ( range) => {
@@ -70,57 +55,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
70
55
Test { span : match_pair. pattern . span , kind }
71
56
}
72
57
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
-
124
58
#[ instrument( skip( self , target_blocks, place_builder) , level = "debug" ) ]
125
59
pub ( super ) fn perform_test (
126
60
& mut self ,
@@ -139,33 +73,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
139
73
140
74
let source_info = self . source_info ( test. span ) ;
141
75
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 } => {
145
77
let otherwise_block = target_block ( TestBranch :: Failure ) ;
146
- let tcx = self . tcx ;
147
78
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) )
156
82
} else {
157
- debug_assert_eq ! (
158
- target_block( TestBranch :: Variant ( idx) ) ,
159
- otherwise_block,
160
- "found candidates for untested discriminant: {discr:?}" ,
161
- ) ;
162
83
None
163
84
}
164
85
} ) ,
165
86
otherwise_block,
166
87
) ;
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 ) ;
169
90
let discr = self . temp ( discr_ty, test. span ) ;
170
91
self . cfg . push_assign (
171
92
block,
@@ -183,13 +104,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
183
104
) ;
184
105
}
185
106
186
- TestKind :: SwitchInt { ref options } => {
107
+ TestKind :: SwitchInt => {
187
108
// The switch may be inexhaustive so we have a catch-all block
188
109
let otherwise_block = target_block ( TestBranch :: Failure ) ;
189
110
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
+ } ) ,
193
118
otherwise_block,
194
119
) ;
195
120
let terminator = TerminatorKind :: SwitchInt {
@@ -548,11 +473,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
548
473
/// that it *doesn't* apply. For now, we return false, indicate that the
549
474
/// test does not apply to this candidate, but it might be we can get
550
475
/// tighter match code if we do something a bit different.
551
- pub ( super ) fn sort_candidate < ' pat > (
476
+ pub ( super ) fn sort_candidate (
552
477
& mut self ,
553
478
test_place : & PlaceBuilder < ' tcx > ,
554
479
test : & Test < ' tcx > ,
555
- candidate : & mut Candidate < ' pat , ' tcx > ,
480
+ candidate : & mut Candidate < ' _ , ' tcx > ,
481
+ sorted_candidates : & FxIndexMap < TestBranch < ' tcx > , Vec < & mut Candidate < ' _ , ' tcx > > > ,
556
482
) -> Option < TestBranch < ' tcx > > {
557
483
// Find the match_pair for this place (if any). At present,
558
484
// afaik, there can be at most one. (In the future, if we
@@ -568,7 +494,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
568
494
// If we are performing a variant switch, then this
569
495
// informs variant patterns, but nothing else.
570
496
(
571
- & TestKind :: Switch { adt_def : tested_adt_def, .. } ,
497
+ & TestKind :: Switch { adt_def : tested_adt_def } ,
572
498
& TestCase :: Variant { adt_def, variant_index } ,
573
499
) => {
574
500
assert_eq ! ( adt_def, tested_adt_def) ;
@@ -581,17 +507,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
581
507
//
582
508
// FIXME(#29623) we could use PatKind::Range to rule
583
509
// things out here, in some cases.
584
- ( TestKind :: SwitchInt { options } , & TestCase :: Constant { value } )
510
+ ( TestKind :: SwitchInt , & TestCase :: Constant { value } )
585
511
if is_switch_ty ( match_pair. pattern . ty ) =>
586
512
{
587
513
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) )
590
516
}
591
- ( TestKind :: SwitchInt { options } , TestCase :: Range ( range) ) => {
517
+ ( TestKind :: SwitchInt , TestCase :: Range ( range) ) => {
592
518
fully_matched = false ;
593
519
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
+ ) ;
595
523
596
524
not_contained. then ( || {
597
525
// No switch values are contained in the pattern range,
@@ -732,20 +660,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
732
660
733
661
ret
734
662
}
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
- }
749
663
}
750
664
751
665
fn is_switch_ty ( ty : Ty < ' _ > ) -> bool {
0 commit comments