@@ -123,16 +123,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
123
123
PatternKind :: Binding { mode : BindingMode :: ByValue ,
124
124
var,
125
125
subpattern : None , .. } => {
126
- self . storage_live_for_bindings ( block, & irrefutable_pat) ;
127
- let lvalue = Lvalue :: Local ( self . var_indices [ & var] ) ;
128
- return self . into ( & lvalue, block, initializer) ;
126
+ let lvalue = self . storage_live_binding ( block, var, irrefutable_pat. span ) ;
127
+ unpack ! ( block = self . into( & lvalue, block, initializer) ) ;
128
+ self . schedule_drop_for_binding ( var, irrefutable_pat. span ) ;
129
+ block. unit ( )
130
+ }
131
+ _ => {
132
+ let lvalue = unpack ! ( block = self . as_lvalue( block, initializer) ) ;
133
+ self . lvalue_into_pattern ( block, irrefutable_pat, & lvalue)
129
134
}
130
- _ => { }
131
135
}
132
- let lvalue = unpack ! ( block = self . as_lvalue( block, initializer) ) ;
133
- self . lvalue_into_pattern ( block,
134
- irrefutable_pat,
135
- & lvalue)
136
136
}
137
137
138
138
pub fn lvalue_into_pattern ( & mut self ,
@@ -174,79 +174,70 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
174
174
scope_span : Span ,
175
175
pattern : & Pattern < ' tcx > )
176
176
-> Option < VisibilityScope > {
177
- match * pattern. kind {
178
- PatternKind :: Binding { mutability, name, mode : _, var, ty, ref subpattern } => {
179
- if var_scope. is_none ( ) {
180
- var_scope = Some ( self . new_visibility_scope ( scope_span) ) ;
181
- }
182
- let source_info = SourceInfo {
183
- span : pattern. span ,
184
- scope : var_scope. unwrap ( )
185
- } ;
186
- self . declare_binding ( source_info, mutability, name, var, ty) ;
187
- if let Some ( subpattern) = subpattern. as_ref ( ) {
188
- var_scope = self . declare_bindings ( var_scope, scope_span, subpattern) ;
189
- }
190
- }
191
- PatternKind :: Array { ref prefix, ref slice, ref suffix } |
192
- PatternKind :: Slice { ref prefix, ref slice, ref suffix } => {
193
- for subpattern in prefix. iter ( ) . chain ( slice) . chain ( suffix) {
194
- var_scope = self . declare_bindings ( var_scope, scope_span, subpattern) ;
195
- }
196
- }
197
- PatternKind :: Constant { .. } | PatternKind :: Range { .. } | PatternKind :: Wild => {
198
- }
199
- PatternKind :: Deref { ref subpattern } => {
200
- var_scope = self . declare_bindings ( var_scope, scope_span, subpattern) ;
201
- }
202
- PatternKind :: Leaf { ref subpatterns } |
203
- PatternKind :: Variant { ref subpatterns, .. } => {
204
- for subpattern in subpatterns {
205
- var_scope = self . declare_bindings ( var_scope, scope_span, & subpattern. pattern ) ;
206
- }
177
+ self . visit_bindings ( pattern, & mut |this, mutability, name, var, span, ty| {
178
+ if var_scope. is_none ( ) {
179
+ var_scope = Some ( this. new_visibility_scope ( scope_span) ) ;
207
180
}
208
- }
181
+ let source_info = SourceInfo {
182
+ span : span,
183
+ scope : var_scope. unwrap ( )
184
+ } ;
185
+ this. declare_binding ( source_info, mutability, name, var, ty) ;
186
+ } ) ;
209
187
var_scope
210
188
}
211
189
212
- /// Emit `StorageLive` for every binding in the pattern.
213
- pub fn storage_live_for_bindings ( & mut self ,
214
- block : BasicBlock ,
215
- pattern : & Pattern < ' tcx > ) {
216
- match * pattern. kind {
217
- PatternKind :: Binding { var, ref subpattern, .. } => {
218
- let lvalue = Lvalue :: Local ( self . var_indices [ & var] ) ;
219
- let source_info = self . source_info ( pattern. span ) ;
220
- self . cfg . push ( block, Statement {
221
- source_info : source_info,
222
- kind : StatementKind :: StorageLive ( lvalue)
223
- } ) ;
190
+ pub fn storage_live_binding ( & mut self , block : BasicBlock , var : NodeId , span : Span )
191
+ -> Lvalue < ' tcx >
192
+ {
193
+ let local_id = self . var_indices [ & var] ;
194
+ let source_info = self . source_info ( span) ;
195
+ self . cfg . push ( block, Statement {
196
+ source_info : source_info,
197
+ kind : StatementKind :: StorageLive ( Lvalue :: Local ( local_id) )
198
+ } ) ;
199
+ Lvalue :: Local ( local_id)
200
+ }
224
201
202
+ pub fn schedule_drop_for_binding ( & mut self , var : NodeId , span : Span ) {
203
+ let local_id = self . var_indices [ & var] ;
204
+ let var_ty = self . local_decls [ local_id] . ty ;
205
+ let extent = self . hir . tcx ( ) . region_maps . var_scope ( var) ;
206
+ self . schedule_drop ( span, extent, & Lvalue :: Local ( local_id) , var_ty) ;
207
+ }
208
+
209
+ pub fn visit_bindings < F > ( & mut self , pattern : & Pattern < ' tcx > , mut f : & mut F )
210
+ where F : FnMut ( & mut Self , Mutability , Name , NodeId , Span , Ty < ' tcx > )
211
+ {
212
+ match * pattern. kind {
213
+ PatternKind :: Binding { mutability, name, var, ty, ref subpattern, .. } => {
214
+ f ( self , mutability, name, var, pattern. span , ty) ;
225
215
if let Some ( subpattern) = subpattern. as_ref ( ) {
226
- self . storage_live_for_bindings ( block , subpattern ) ;
216
+ self . visit_bindings ( subpattern , f ) ;
227
217
}
228
218
}
229
219
PatternKind :: Array { ref prefix, ref slice, ref suffix } |
230
220
PatternKind :: Slice { ref prefix, ref slice, ref suffix } => {
231
221
for subpattern in prefix. iter ( ) . chain ( slice) . chain ( suffix) {
232
- self . storage_live_for_bindings ( block , subpattern ) ;
222
+ self . visit_bindings ( subpattern , f ) ;
233
223
}
234
224
}
235
225
PatternKind :: Constant { .. } | PatternKind :: Range { .. } | PatternKind :: Wild => {
236
226
}
237
227
PatternKind :: Deref { ref subpattern } => {
238
- self . storage_live_for_bindings ( block , subpattern ) ;
228
+ self . visit_bindings ( subpattern , f ) ;
239
229
}
240
230
PatternKind :: Leaf { ref subpatterns } |
241
231
PatternKind :: Variant { ref subpatterns, .. } => {
242
232
for subpattern in subpatterns {
243
- self . storage_live_for_bindings ( block , & subpattern. pattern ) ;
233
+ self . visit_bindings ( & subpattern. pattern , f ) ;
244
234
}
245
235
}
246
236
}
247
237
}
248
238
}
249
239
240
+
250
241
/// List of blocks for each arm (and potentially other metadata in the
251
242
/// future).
252
243
struct ArmBlocks {
@@ -691,25 +682,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
691
682
692
683
// Assign each of the bindings. This may trigger moves out of the candidate.
693
684
for binding in bindings {
694
- // Find the variable for the `var_id` being bound. It
695
- // should have been created by a previous call to
696
- // `declare_bindings`.
697
- let var_index = self . var_indices [ & binding. var_id ] ;
698
-
685
+ let source_info = self . source_info ( binding. span ) ;
686
+ let local = self . storage_live_binding ( block, binding. var_id , binding. span ) ;
687
+ self . schedule_drop_for_binding ( binding. var_id , binding. span ) ;
699
688
let rvalue = match binding. binding_mode {
700
689
BindingMode :: ByValue =>
701
690
Rvalue :: Use ( Operand :: Consume ( binding. source ) ) ,
702
691
BindingMode :: ByRef ( region, borrow_kind) =>
703
692
Rvalue :: Ref ( region, borrow_kind, binding. source ) ,
704
693
} ;
705
-
706
- let source_info = self . source_info ( binding. span ) ;
707
- self . cfg . push ( block, Statement {
708
- source_info : source_info,
709
- kind : StatementKind :: StorageLive ( Lvalue :: Local ( var_index) )
710
- } ) ;
711
- self . cfg . push_assign ( block, source_info,
712
- & Lvalue :: Local ( var_index) , rvalue) ;
694
+ self . cfg . push_assign ( block, source_info, & local, rvalue) ;
713
695
}
714
696
}
715
697
@@ -730,8 +712,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
730
712
name : Some ( name) ,
731
713
source_info : Some ( source_info) ,
732
714
} ) ;
733
- let extent = self . hir . tcx ( ) . region_maps . var_scope ( var_id) ;
734
- self . schedule_drop ( source_info. span , extent, & Lvalue :: Local ( var) , var_ty) ;
735
715
self . var_indices . insert ( var_id, var) ;
736
716
737
717
debug ! ( "declare_binding: var={:?}" , var) ;
0 commit comments