@@ -337,18 +337,18 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
337
337
self . drop_ladder ( fields, succ, unwind) . 0
338
338
}
339
339
340
- fn open_drop_for_box < ' a > ( & mut self , ty : Ty < ' tcx > ) -> BasicBlock
340
+ fn open_drop_for_box < ' a > ( & mut self , box_ty : Ty < ' tcx > ) -> BasicBlock
341
341
{
342
- debug ! ( "open_drop_for_box({:?}, {:?})" , self , ty ) ;
342
+ debug ! ( "open_drop_for_box({:?}, {:?})" , self , box_ty ) ;
343
343
344
344
let interior = self . place . clone ( ) . deref ( ) ;
345
345
let interior_path = self . elaborator . deref_subpath ( self . path ) ;
346
346
347
347
let succ = self . succ ; // FIXME(#6393)
348
348
let unwind = self . unwind ;
349
- let succ = self . box_free_block ( ty , succ, unwind) ;
349
+ let succ = self . box_free_block ( box_ty , succ, unwind) ;
350
350
let unwind_succ = self . unwind . map ( |unwind| {
351
- self . box_free_block ( ty , unwind, Unwind :: InCleanup )
351
+ self . box_free_block ( box_ty , unwind, Unwind :: InCleanup )
352
352
} ) ;
353
353
354
354
self . drop_subpath ( & interior, interior_path, succ, unwind_succ)
@@ -788,7 +788,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
788
788
self . open_drop_for_tuple ( tys)
789
789
}
790
790
ty:: TyAdt ( def, _) if def. is_box ( ) => {
791
- self . open_drop_for_box ( ty. boxed_ty ( ) )
791
+ self . open_drop_for_box ( ty)
792
792
}
793
793
ty:: TyAdt ( def, substs) => {
794
794
self . open_drop_for_adt ( def, substs)
@@ -854,28 +854,39 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
854
854
855
855
fn box_free_block < ' a > (
856
856
& mut self ,
857
- ty : Ty < ' tcx > ,
857
+ box_ty : Ty < ' tcx > ,
858
858
target : BasicBlock ,
859
859
unwind : Unwind ,
860
860
) -> BasicBlock {
861
- let block = self . unelaborated_free_block ( ty , target, unwind) ;
861
+ let block = self . unelaborated_free_block ( box_ty , target, unwind) ;
862
862
self . drop_flag_test_block ( block, target, unwind)
863
863
}
864
864
865
865
fn unelaborated_free_block < ' a > (
866
866
& mut self ,
867
- ty : Ty < ' tcx > ,
867
+ box_ty : Ty < ' tcx > ,
868
868
target : BasicBlock ,
869
869
unwind : Unwind
870
870
) -> BasicBlock {
871
871
let tcx = self . tcx ( ) ;
872
872
let unit_temp = Place :: Local ( self . new_temp ( tcx. mk_nil ( ) ) ) ;
873
873
let free_func = tcx. require_lang_item ( lang_items:: BoxFreeFnLangItem ) ;
874
- let substs = tcx. mk_substs ( iter:: once ( Kind :: from ( ty) ) ) ;
874
+
875
+ // Use the generic parameters of `Box` for `box_free`, and the
876
+ // fields of `Box` as arguments. Their types should always match.
877
+ let ( substs, args) = match box_ty. sty {
878
+ ty:: TyAdt ( def, substs) => {
879
+ ( substs, def. struct_variant ( ) . fields . iter ( ) . enumerate ( ) . map ( |( i, f) | {
880
+ let box_place = self . place . clone ( ) ;
881
+ Operand :: Move ( box_place. field ( Field :: new ( i) , f. ty ( tcx, substs) ) )
882
+ } ) . collect ( ) )
883
+ }
884
+ _ => bug ! ( "expected Box<T> to be a struct, found `{:?}`" , box_ty)
885
+ } ;
875
886
876
887
let call = TerminatorKind :: Call {
877
888
func : Operand :: function_handle ( tcx, free_func, substs, self . source_info . span ) ,
878
- args : vec ! [ Operand :: Move ( self . place . clone ( ) ) ] ,
889
+ args,
879
890
destination : Some ( ( unit_temp, target) ) ,
880
891
cleanup : None
881
892
} ; // FIXME(#6393)
0 commit comments