@@ -37,25 +37,28 @@ impl<'a,'tcx> Builder<'a,'tcx> {
3737 -> BlockAnd < ( ) > {
3838 let discriminant_lvalue = unpack ! ( block = self . as_lvalue( block, discriminant) ) ;
3939
40- // Before we do anything, create uninitialized variables with
41- // suitable extent for all of the bindings in this match. It's
42- // easiest to do this up front because some of these arms may
43- // be unreachable or reachable multiple times.
44- let var_scope_id = self . innermost_scope_id ( ) ;
45- for arm in & arms {
46- self . declare_bindings ( var_scope_id, & arm. patterns [ 0 ] ) ;
47- }
48-
4940 let mut arm_blocks = ArmBlocks {
5041 blocks : arms. iter ( )
5142 . map ( |_| self . cfg . start_new_block ( ) )
5243 . collect ( ) ,
5344 } ;
5445
55- let arm_bodies: Vec < ExprRef < ' tcx > > =
56- arms. iter ( )
57- . map ( |arm| arm. body . clone ( ) )
58- . collect ( ) ;
46+ // Get the body expressions and their scopes, while declaring bindings.
47+ let arm_bodies: Vec < _ > = arms. iter ( ) . enumerate ( ) . map ( |( i, arm) | {
48+ // Assume that all expressions are wrapped in Scope.
49+ let body = self . hir . mirror ( arm. body . clone ( ) ) ;
50+ match body. kind {
51+ ExprKind :: Scope { extent, value } => {
52+ let scope_id = self . push_scope ( extent, arm_blocks. blocks [ i] ) ;
53+ self . declare_bindings ( scope_id, & arm. patterns [ 0 ] ) ;
54+ ( extent, self . scopes . pop ( ) . unwrap ( ) , value)
55+ }
56+ _ => {
57+ span_bug ! ( body. span, "arm body is not wrapped in Scope {:?}" ,
58+ body. kind) ;
59+ }
60+ }
61+ } ) . collect ( ) ;
5962
6063 // assemble a list of candidates: there is one candidate per
6164 // pattern, which means there may be more than one candidate
@@ -95,11 +98,15 @@ impl<'a,'tcx> Builder<'a,'tcx> {
9598 // all the arm blocks will rejoin here
9699 let end_block = self . cfg . start_new_block ( ) ;
97100
98- for ( arm_index, arm_body) in arm_bodies. into_iter ( ) . enumerate ( ) {
101+ let scope_id = self . innermost_scope_id ( ) ;
102+ for ( arm_index, ( extent, scope, body) ) in arm_bodies. into_iter ( ) . enumerate ( ) {
99103 let mut arm_block = arm_blocks. blocks [ arm_index] ;
100- unpack ! ( arm_block = self . into( destination, arm_block, arm_body) ) ;
104+ // Re-enter the scope we created the bindings in.
105+ self . scopes . push ( scope) ;
106+ unpack ! ( arm_block = self . into( destination, arm_block, body) ) ;
107+ unpack ! ( arm_block = self . pop_scope( extent, arm_block) ) ;
101108 self . cfg . terminate ( arm_block,
102- var_scope_id ,
109+ scope_id ,
103110 span,
104111 TerminatorKind :: Goto { target : end_block } ) ;
105112 }
0 commit comments