@@ -19,6 +19,7 @@ use build::Builder;
1919use build:: matches:: { Candidate , MatchPair , Test , TestKind } ;
2020use hair:: * ;
2121use rustc_data_structures:: fnv:: FnvHashMap ;
22+ use rustc_data_structures:: bitvec:: BitVector ;
2223use rustc:: middle:: const_val:: ConstVal ;
2324use rustc:: ty:: { self , Ty } ;
2425use rustc:: mir:: repr:: * ;
@@ -35,7 +36,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
3536 span : match_pair. pattern . span ,
3637 kind : TestKind :: Switch {
3738 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) ) ,
3940 } ,
4041 }
4142 }
@@ -129,7 +130,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
129130 true
130131 }
131132 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!" ) ;
133134 }
134135 PatternKind :: Range { .. } |
135136 PatternKind :: Slice { .. } |
@@ -145,10 +146,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
145146 }
146147
147148 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
152153 {
153154 let match_pair = match candidate. match_pairs . iter ( ) . find ( |mp| mp. lvalue == * test_lvalue) {
154155 Some ( match_pair) => match_pair,
@@ -157,8 +158,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
157158
158159 match * match_pair. pattern . kind {
159160 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) ;
162164 true
163165 }
164166 _ => {
@@ -178,24 +180,19 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
178180 match test. kind {
179181 TestKind :: Switch { adt_def, ref variants } => {
180182 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 ( ) ) ;
192190 }
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) ;
199196 self . cfg . terminate ( block, scope_id, test. span , TerminatorKind :: Switch {
200197 discr : lvalue. clone ( ) ,
201198 adt_def : adt_def,
0 commit comments