@@ -236,7 +236,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
236
236
self . diverge_cleanup ( ) ;
237
237
let scope = self . scopes . pop ( ) . unwrap ( ) ;
238
238
assert_eq ! ( scope. extent, extent) ;
239
- build_scope_drops ( block , & scope, & self . scopes [ ..] , & mut self . cfg )
239
+ build_scope_drops ( & mut self . cfg , & scope, & self . scopes [ ..] , block )
240
240
}
241
241
242
242
@@ -254,8 +254,18 @@ impl<'a,'tcx> Builder<'a,'tcx> {
254
254
self . hir . span_bug ( span, & format ! ( "extent {:?} does not enclose" , extent) )
255
255
} ) ;
256
256
257
+ let tmp = self . get_unit_temp ( ) ;
257
258
for ( idx, ref scope) in self . scopes . iter ( ) . enumerate ( ) . rev ( ) . take ( scope_count) {
258
- unpack ! ( block = build_scope_drops( block, scope, & self . scopes[ ..idx] , & mut self . cfg) ) ;
259
+ unpack ! ( block = build_scope_drops( & mut self . cfg,
260
+ scope,
261
+ & self . scopes[ ..idx] ,
262
+ block) ) ;
263
+ if let Some ( ref free_data) = scope. free {
264
+ let next = self . cfg . start_new_block ( ) ;
265
+ let free = build_free ( self . hir . tcx ( ) , tmp. clone ( ) , free_data, next) ;
266
+ self . cfg . terminate ( block, free) ;
267
+ block = next;
268
+ }
259
269
}
260
270
self . cfg . terminate ( block, Terminator :: Goto { target : target } ) ;
261
271
}
@@ -508,10 +518,10 @@ impl<'a,'tcx> Builder<'a,'tcx> {
508
518
}
509
519
510
520
/// Builds drops for pop_scope and exit_scope.
511
- fn build_scope_drops < ' tcx > ( mut block : BasicBlock ,
521
+ fn build_scope_drops < ' tcx > ( cfg : & mut CFG < ' tcx > ,
512
522
scope : & Scope < ' tcx > ,
513
523
earlier_scopes : & [ Scope < ' tcx > ] ,
514
- cfg : & mut CFG < ' tcx > )
524
+ mut block : BasicBlock )
515
525
-> BlockAnd < ( ) > {
516
526
let mut iter = scope. drops . iter ( ) . rev ( ) . peekable ( ) ;
517
527
while let Some ( drop_data) = iter. next ( ) {
@@ -586,9 +596,10 @@ fn build_diverge_scope<'tcx>(tcx: &ty::ctxt<'tcx>,
586
596
target = if let Some ( cached_block) = free_data. cached_block {
587
597
cached_block
588
598
} else {
589
- let t = build_free ( tcx, cfg, unit_temp, free_data, target) ;
590
- free_data. cached_block = Some ( t) ;
591
- t
599
+ let into = cfg. start_new_cleanup_block ( ) ;
600
+ cfg. terminate ( into, build_free ( tcx, unit_temp, free_data, target) ) ;
601
+ free_data. cached_block = Some ( into) ;
602
+ into
592
603
}
593
604
} ;
594
605
@@ -608,19 +619,16 @@ fn build_diverge_scope<'tcx>(tcx: &ty::ctxt<'tcx>,
608
619
}
609
620
610
621
fn build_free < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
611
- cfg : & mut CFG < ' tcx > ,
612
622
unit_temp : Lvalue < ' tcx > ,
613
623
data : & FreeData < ' tcx > ,
614
- target : BasicBlock )
615
- -> BasicBlock {
624
+ target : BasicBlock ) -> Terminator < ' tcx > {
616
625
let free_func = tcx. lang_items . box_free_fn ( )
617
626
. expect ( "box_free language item is missing" ) ;
618
627
let substs = tcx. mk_substs ( Substs :: new (
619
628
VecPerParamSpace :: new ( vec ! [ ] , vec ! [ ] , vec ! [ data. item_ty] ) ,
620
629
VecPerParamSpace :: new ( vec ! [ ] , vec ! [ ] , vec ! [ ] )
621
630
) ) ;
622
- let block = cfg. start_new_cleanup_block ( ) ;
623
- cfg. terminate ( block, Terminator :: Call {
631
+ Terminator :: Call {
624
632
func : Operand :: Constant ( Constant {
625
633
span : data. span ,
626
634
ty : tcx. lookup_item_type ( free_func) . ty . subst ( tcx, substs) ,
@@ -633,6 +641,5 @@ fn build_free<'tcx>(tcx: &ty::ctxt<'tcx>,
633
641
args : vec ! [ Operand :: Consume ( data. value. clone( ) ) ] ,
634
642
destination : Some ( ( unit_temp, target) ) ,
635
643
cleanup : None
636
- } ) ;
637
- block
644
+ }
638
645
}
0 commit comments