@@ -123,16 +123,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
123123 PatternKind :: Binding { mode : BindingMode :: ByValue ,
124124 var,
125125 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)
129134 }
130- _ => { }
131135 }
132- let lvalue = unpack ! ( block = self . as_lvalue( block, initializer) ) ;
133- self . lvalue_into_pattern ( block,
134- irrefutable_pat,
135- & lvalue)
136136 }
137137
138138 pub fn lvalue_into_pattern ( & mut self ,
@@ -174,79 +174,70 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
174174 scope_span : Span ,
175175 pattern : & Pattern < ' tcx > )
176176 -> 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) ) ;
207180 }
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+ } ) ;
209187 var_scope
210188 }
211189
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+ }
224201
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) ;
225215 if let Some ( subpattern) = subpattern. as_ref ( ) {
226- self . storage_live_for_bindings ( block , subpattern ) ;
216+ self . visit_bindings ( subpattern , f ) ;
227217 }
228218 }
229219 PatternKind :: Array { ref prefix, ref slice, ref suffix } |
230220 PatternKind :: Slice { ref prefix, ref slice, ref suffix } => {
231221 for subpattern in prefix. iter ( ) . chain ( slice) . chain ( suffix) {
232- self . storage_live_for_bindings ( block , subpattern ) ;
222+ self . visit_bindings ( subpattern , f ) ;
233223 }
234224 }
235225 PatternKind :: Constant { .. } | PatternKind :: Range { .. } | PatternKind :: Wild => {
236226 }
237227 PatternKind :: Deref { ref subpattern } => {
238- self . storage_live_for_bindings ( block , subpattern ) ;
228+ self . visit_bindings ( subpattern , f ) ;
239229 }
240230 PatternKind :: Leaf { ref subpatterns } |
241231 PatternKind :: Variant { ref subpatterns, .. } => {
242232 for subpattern in subpatterns {
243- self . storage_live_for_bindings ( block , & subpattern. pattern ) ;
233+ self . visit_bindings ( & subpattern. pattern , f ) ;
244234 }
245235 }
246236 }
247237 }
248238}
249239
240+
250241/// List of blocks for each arm (and potentially other metadata in the
251242/// future).
252243struct ArmBlocks {
@@ -691,25 +682,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
691682
692683 // Assign each of the bindings. This may trigger moves out of the candidate.
693684 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 ) ;
699688 let rvalue = match binding. binding_mode {
700689 BindingMode :: ByValue =>
701690 Rvalue :: Use ( Operand :: Consume ( binding. source ) ) ,
702691 BindingMode :: ByRef ( region, borrow_kind) =>
703692 Rvalue :: Ref ( region, borrow_kind, binding. source ) ,
704693 } ;
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) ;
713695 }
714696 }
715697
@@ -730,8 +712,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
730712 name : Some ( name) ,
731713 source_info : Some ( source_info) ,
732714 } ) ;
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) ;
735715 self . var_indices . insert ( var_id, var) ;
736716
737717 debug ! ( "declare_binding: var={:?}" , var) ;
0 commit comments