@@ -33,7 +33,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
33
33
PatternKind :: Variant { ref adt_def, variant_index : _, subpatterns : _ } => {
34
34
Test {
35
35
span : match_pair. pattern . span ,
36
- kind : TestKind :: Switch { adt_def : adt_def. clone ( ) } ,
36
+ kind : TestKind :: Switch {
37
+ adt_def : adt_def. clone ( ) ,
38
+ variants : vec ! [ false ; self . hir. num_variants( adt_def) ] ,
39
+ } ,
37
40
}
38
41
}
39
42
@@ -125,9 +128,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
125
128
} ) ;
126
129
true
127
130
}
128
-
131
+ PatternKind :: Variant { .. } => {
132
+ panic ! ( "you should have called add_cases_to_switch_switch instead!" ) ;
133
+ }
129
134
PatternKind :: Range { .. } |
130
- PatternKind :: Variant { .. } |
131
135
PatternKind :: Slice { .. } |
132
136
PatternKind :: Array { .. } |
133
137
PatternKind :: Wild |
@@ -140,6 +144,30 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
140
144
}
141
145
}
142
146
147
+ 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
152
+ {
153
+ let match_pair = match candidate. match_pairs . iter ( ) . find ( |mp| mp. lvalue == * test_lvalue) {
154
+ Some ( match_pair) => match_pair,
155
+ _ => { return false ; }
156
+ } ;
157
+
158
+ match * match_pair. pattern . kind {
159
+ PatternKind :: Variant { adt_def : _ , variant_index, .. } => {
160
+ // Do I need to look at the PatternKind::Variant subpatterns?
161
+ variants[ variant_index] |= true ;
162
+ true
163
+ }
164
+ _ => {
165
+ // don't know how to add these patterns to a switch
166
+ false
167
+ }
168
+ }
169
+ }
170
+
143
171
/// Generates the code to perform a test.
144
172
pub fn perform_test ( & mut self ,
145
173
block : BasicBlock ,
@@ -148,11 +176,26 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
148
176
-> Vec < BasicBlock > {
149
177
let scope_id = self . innermost_scope_id ( ) ;
150
178
match test. kind {
151
- TestKind :: Switch { adt_def } => {
179
+ TestKind :: Switch { adt_def, ref variants } => {
152
180
let num_enum_variants = self . hir . num_variants ( adt_def) ;
153
- let target_blocks: Vec < _ > =
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
192
+ }
193
+ )
194
+ . collect ( )
195
+ } else {
154
196
( 0 ..num_enum_variants) . map ( |_| self . cfg . start_new_block ( ) )
155
- . collect ( ) ;
197
+ . collect ( )
198
+ } ;
156
199
self . cfg . terminate ( block, scope_id, test. span , TerminatorKind :: Switch {
157
200
discr : lvalue. clone ( ) ,
158
201
adt_def : adt_def,
@@ -383,7 +426,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
383
426
match test. kind {
384
427
// If we are performing a variant switch, then this
385
428
// informs variant patterns, but nothing else.
386
- TestKind :: Switch { adt_def : tested_adt_def } => {
429
+ TestKind :: Switch { adt_def : tested_adt_def , .. } => {
387
430
match * match_pair. pattern . kind {
388
431
PatternKind :: Variant { adt_def, variant_index, ref subpatterns } => {
389
432
assert_eq ! ( adt_def, tested_adt_def) ;
0 commit comments