@@ -34,6 +34,15 @@ impl<H:Hair> Builder<H> {
3434 let discriminant_lvalue =
3535 unpack ! ( block = self . as_lvalue( block, discriminant) ) ;
3636
37+ // Before we do anything, create uninitialized variables with
38+ // suitable extent for all of the bindings in this match. It's
39+ // easiest to do this up front because some of these arms may
40+ // be unreachable or reachable multiple times.
41+ let var_extent = self . extent_of_innermost_scope ( ) . unwrap ( ) ;
42+ for arm in & arms {
43+ self . declare_bindings ( var_extent, arm. patterns [ 0 ] . clone ( ) ) ;
44+ }
45+
3746 let mut arm_blocks = ArmBlocks {
3847 blocks : arms. iter ( )
3948 . map ( |_| self . cfg . start_new_block ( ) )
@@ -52,14 +61,13 @@ impl<H:Hair> Builder<H> {
5261 // reverse of the order in which candidates are written in the
5362 // source.
5463 let candidates: Vec < Candidate < H > > =
55- arms. into_iter ( )
64+ arms. iter ( )
5665 . enumerate ( )
5766 . rev ( ) // highest priority comes last
5867 . flat_map ( |( arm_index, arm) | {
59- let guard = arm. guard ;
60- arm. patterns . into_iter ( )
68+ arm. patterns . iter ( )
6169 . rev ( )
62- . map ( move |pat| ( arm_index, pat, guard. clone ( ) ) )
70+ . map ( move |pat| ( arm_index, pat. clone ( ) , arm . guard . clone ( ) ) )
6371 } )
6472 . map ( |( arm_index, pattern, guard) | {
6573 Candidate {
@@ -73,8 +81,7 @@ impl<H:Hair> Builder<H> {
7381
7482 // this will generate code to test discriminant_lvalue and
7583 // branch to the appropriate arm block
76- let var_extent = self . extent_of_innermost_scope ( ) . unwrap ( ) ;
77- self . match_candidates ( span, var_extent, & mut arm_blocks, candidates, block) ;
84+ self . match_candidates ( span, & mut arm_blocks, candidates, block) ;
7885
7986 // all the arm blocks will rejoin here
8087 let end_block = self . cfg . start_new_block ( ) ;
@@ -123,9 +130,12 @@ impl<H:Hair> Builder<H> {
123130 initializer : & Lvalue < H > )
124131 -> BlockAnd < ( ) >
125132 {
133+ // first, creating the bindings
134+ self . declare_bindings ( var_extent, irrefutable_pat. clone ( ) ) ;
135+
126136 // create a dummy candidate
127137 let mut candidate = Candidate :: < H > {
128- match_pairs : vec ! [ self . match_pair( initializer. clone( ) , irrefutable_pat) ] ,
138+ match_pairs : vec ! [ self . match_pair( initializer. clone( ) , irrefutable_pat. clone ( ) ) ] ,
129139 bindings : vec ! [ ] ,
130140 guard : None ,
131141 arm_index : 0 , // since we don't call `match_candidates`, this field is unused
@@ -143,38 +153,38 @@ impl<H:Hair> Builder<H> {
143153 }
144154
145155 // now apply the bindings, which will also declare the variables
146- self . bind_matched_candidate ( block, var_extent , candidate. bindings ) ;
156+ self . bind_matched_candidate ( block, candidate. bindings ) ;
147157
148158 block. unit ( )
149159 }
150160
151- pub fn declare_uninitialized_variables ( & mut self ,
152- var_extent : H :: CodeExtent ,
153- pattern : PatternRef < H > )
161+ pub fn declare_bindings ( & mut self ,
162+ var_extent : H :: CodeExtent ,
163+ pattern : PatternRef < H > )
154164 {
155165 let pattern = self . hir . mirror ( pattern) ;
156166 match pattern. kind {
157167 PatternKind :: Binding { mutability, name, mode : _, var, ty, subpattern } => {
158168 self . declare_binding ( var_extent, mutability, name, var, ty, pattern. span ) ;
159169 if let Some ( subpattern) = subpattern {
160- self . declare_uninitialized_variables ( var_extent, subpattern) ;
170+ self . declare_bindings ( var_extent, subpattern) ;
161171 }
162172 }
163173 PatternKind :: Array { prefix, slice, suffix } |
164174 PatternKind :: Slice { prefix, slice, suffix } => {
165175 for subpattern in prefix. into_iter ( ) . chain ( slice) . chain ( suffix) {
166- self . declare_uninitialized_variables ( var_extent, subpattern) ;
176+ self . declare_bindings ( var_extent, subpattern) ;
167177 }
168178 }
169179 PatternKind :: Constant { .. } | PatternKind :: Range { .. } | PatternKind :: Wild => {
170180 }
171181 PatternKind :: Deref { subpattern } => {
172- self . declare_uninitialized_variables ( var_extent, subpattern) ;
182+ self . declare_bindings ( var_extent, subpattern) ;
173183 }
174184 PatternKind :: Leaf { subpatterns } |
175185 PatternKind :: Variant { subpatterns, .. } => {
176186 for subpattern in subpatterns {
177- self . declare_uninitialized_variables ( var_extent, subpattern. pattern ) ;
187+ self . declare_bindings ( var_extent, subpattern. pattern ) ;
178188 }
179189 }
180190 }
@@ -249,13 +259,12 @@ struct Test<H:Hair> {
249259impl < H : Hair > Builder < H > {
250260 fn match_candidates ( & mut self ,
251261 span : H :: Span ,
252- var_extent : H :: CodeExtent ,
253262 arm_blocks : & mut ArmBlocks ,
254263 mut candidates : Vec < Candidate < H > > ,
255264 mut block : BasicBlock )
256265 {
257- debug ! ( "matched_candidate(span={:?}, var_extent={:?}, block={:?}, candidates={:?})" ,
258- span, var_extent , block, candidates) ;
266+ debug ! ( "matched_candidate(span={:?}, block={:?}, candidates={:?})" ,
267+ span, block, candidates) ;
259268
260269 // Start by simplifying candidates. Once this process is
261270 // complete, all the match pairs which remain require some
@@ -275,8 +284,7 @@ impl<H:Hair> Builder<H> {
275284 // If so, apply any bindings, test the guard (if any), and
276285 // branch to the arm.
277286 let candidate = candidates. pop ( ) . unwrap ( ) ;
278- if let Some ( b) = self . bind_and_guard_matched_candidate ( block, var_extent,
279- arm_blocks, candidate) {
287+ if let Some ( b) = self . bind_and_guard_matched_candidate ( block, arm_blocks, candidate) {
280288 block = b;
281289 } else {
282290 // if None is returned, then any remaining candidates
@@ -309,7 +317,7 @@ impl<H:Hair> Builder<H> {
309317 candidate) )
310318 } )
311319 . collect ( ) ;
312- self . match_candidates ( span, var_extent , arm_blocks, applicable_candidates, target_block) ;
320+ self . match_candidates ( span, arm_blocks, applicable_candidates, target_block) ;
313321 }
314322 }
315323
@@ -327,16 +335,15 @@ impl<H:Hair> Builder<H> {
327335 /// MIR).
328336 fn bind_and_guard_matched_candidate ( & mut self ,
329337 mut block : BasicBlock ,
330- var_extent : H :: CodeExtent ,
331338 arm_blocks : & mut ArmBlocks ,
332339 candidate : Candidate < H > )
333340 -> Option < BasicBlock > {
334- debug ! ( "bind_and_guard_matched_candidate(block={:?}, var_extent={:?}, candidate={:?})" ,
335- block, var_extent , candidate) ;
341+ debug ! ( "bind_and_guard_matched_candidate(block={:?}, candidate={:?})" ,
342+ block, candidate) ;
336343
337344 debug_assert ! ( candidate. match_pairs. is_empty( ) ) ;
338345
339- self . bind_matched_candidate ( block, var_extent , candidate. bindings ) ;
346+ self . bind_matched_candidate ( block, candidate. bindings ) ;
340347
341348 let arm_block = arm_blocks. blocks [ candidate. arm_index ] ;
342349
@@ -356,26 +363,16 @@ impl<H:Hair> Builder<H> {
356363
357364 fn bind_matched_candidate ( & mut self ,
358365 block : BasicBlock ,
359- var_extent : H :: CodeExtent ,
360366 bindings : Vec < Binding < H > > ) {
361- debug ! ( "bind_matched_candidate(block={:?}, var_extent={:?}, bindings={:?})" ,
362- block, var_extent , bindings) ;
367+ debug ! ( "bind_matched_candidate(block={:?}, bindings={:?})" ,
368+ block, bindings) ;
363369
364370 // Assign each of the bindings. This may trigger moves out of the candidate.
365371 for binding in bindings {
366- // Create a variable for the `var_id` being bound. In the
367- // case where there are multiple patterns for a single
368- // arm, it may already exist.
369- let var_index = if !self . var_indices . contains_key ( & binding. var_id ) {
370- self . declare_binding ( var_extent,
371- binding. mutability ,
372- binding. name ,
373- binding. var_id ,
374- binding. var_ty ,
375- binding. span )
376- } else {
377- self . var_indices [ & binding. var_id ]
378- } ;
372+ // Find the variable for the `var_id` being bound. It
373+ // should have been created by a previous call to
374+ // `declare_bindings`.
375+ let var_index = self . var_indices [ & binding. var_id ] ;
379376
380377 let rvalue = match binding. binding_mode {
381378 BindingMode :: ByValue =>
0 commit comments