@@ -19,6 +19,7 @@ use build::Builder;
19
19
use build:: matches:: { Candidate , MatchPair , Test , TestKind } ;
20
20
use hair:: * ;
21
21
use rustc_data_structures:: fnv:: FnvHashMap ;
22
+ use rustc_data_structures:: bitvec:: BitVector ;
22
23
use rustc:: middle:: const_val:: ConstVal ;
23
24
use rustc:: ty:: { self , Ty } ;
24
25
use rustc:: mir:: repr:: * ;
@@ -35,7 +36,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
35
36
span : match_pair. pattern . span ,
36
37
kind : TestKind :: Switch {
37
38
adt_def : adt_def. clone ( ) ,
38
- variants : vec ! [ false ; self . hir. num_variants( adt_def) ] ,
39
+ variants : BitVector :: new ( self . hir . num_variants ( adt_def) ) ,
39
40
} ,
40
41
}
41
42
}
@@ -129,7 +130,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
129
130
true
130
131
}
131
132
PatternKind :: Variant { .. } => {
132
- panic ! ( "you should have called add_cases_to_switch_switch instead!" ) ;
133
+ panic ! ( "you should have called add_variants_to_switch instead!" ) ;
133
134
}
134
135
PatternKind :: Range { .. } |
135
136
PatternKind :: Slice { .. } |
@@ -145,10 +146,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
145
146
}
146
147
147
148
pub fn add_variants_to_switch < ' pat > ( & mut self ,
148
- test_lvalue : & Lvalue < ' tcx > ,
149
- candidate : & Candidate < ' pat , ' tcx > ,
150
- variants : & mut Vec < bool > )
151
- -> bool
149
+ test_lvalue : & Lvalue < ' tcx > ,
150
+ candidate : & Candidate < ' pat , ' tcx > ,
151
+ variants : & mut BitVector )
152
+ -> bool
152
153
{
153
154
let match_pair = match candidate. match_pairs . iter ( ) . find ( |mp| mp. lvalue == * test_lvalue) {
154
155
Some ( match_pair) => match_pair,
@@ -157,8 +158,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
157
158
158
159
match * match_pair. pattern . kind {
159
160
PatternKind :: Variant { adt_def : _ , variant_index, .. } => {
160
- // Do I need to look at the PatternKind::Variant subpatterns?
161
- variants[ variant_index] |= true ;
161
+ // We have a pattern testing for variant `variant_index`
162
+ // set the corresponding index to true
163
+ variants. insert ( variant_index) ;
162
164
true
163
165
}
164
166
_ => {
@@ -178,24 +180,19 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
178
180
match test. kind {
179
181
TestKind :: Switch { adt_def, ref variants } => {
180
182
let num_enum_variants = self . hir . num_variants ( adt_def) ;
181
- debug ! ( "num_enum_variants: {}" , num_enum_variants) ;
182
- debug ! ( "variants.len(): {}" , variants. len( ) ) ;
183
- debug ! ( "variants: {:?}" , variants) ;
184
- let target_blocks: Vec < _ > = if variants. into_iter ( ) . any ( |b| { !b} ) {
185
- let otherwise_block = self . cfg . start_new_block ( ) ;
186
- debug ! ( "basic block: {:?} is an otherwise block!" , otherwise_block) ;
187
- ( 0 ..num_enum_variants) . map ( |i|
188
- if variants[ i] {
189
- self . cfg . start_new_block ( )
190
- } else {
191
- otherwise_block
183
+ let mut otherwise_block = None ;
184
+ let target_blocks: Vec < _ > = ( 0 ..num_enum_variants) . map ( |i| {
185
+ if variants. contains ( i) {
186
+ self . cfg . start_new_block ( )
187
+ } else {
188
+ if otherwise_block. is_none ( ) {
189
+ otherwise_block = Some ( self . cfg . start_new_block ( ) ) ;
192
190
}
193
- )
194
- . collect ( )
195
- } else {
196
- ( 0 ..num_enum_variants) . map ( |_| self . cfg . start_new_block ( ) )
197
- . collect ( )
198
- } ;
191
+ otherwise_block. unwrap ( )
192
+ }
193
+ } ) . collect ( ) ;
194
+ debug ! ( "num_enum_variants: {}, num tested variants: {}, variants: {:?}" ,
195
+ num_enum_variants, variants. iter( ) . count( ) , variants) ;
199
196
self . cfg . terminate ( block, scope_id, test. span , TerminatorKind :: Switch {
200
197
discr : lvalue. clone ( ) ,
201
198
adt_def : adt_def,
0 commit comments