@@ -37,25 +37,28 @@ impl<'a,'tcx> Builder<'a,'tcx> {
37
37
-> BlockAnd < ( ) > {
38
38
let discriminant_lvalue = unpack ! ( block = self . as_lvalue( block, discriminant) ) ;
39
39
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
-
49
40
let mut arm_blocks = ArmBlocks {
50
41
blocks : arms. iter ( )
51
42
. map ( |_| self . cfg . start_new_block ( ) )
52
43
. collect ( ) ,
53
44
} ;
54
45
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 ( ) ;
59
62
60
63
// assemble a list of candidates: there is one candidate per
61
64
// pattern, which means there may be more than one candidate
@@ -95,11 +98,15 @@ impl<'a,'tcx> Builder<'a,'tcx> {
95
98
// all the arm blocks will rejoin here
96
99
let end_block = self . cfg . start_new_block ( ) ;
97
100
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 ( ) {
99
103
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) ) ;
101
108
self . cfg . terminate ( arm_block,
102
- var_scope_id ,
109
+ scope_id ,
103
110
span,
104
111
TerminatorKind :: Goto { target : end_block } ) ;
105
112
}
0 commit comments