@@ -337,18 +337,18 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
337337 self . drop_ladder ( fields, succ, unwind) . 0
338338 }
339339
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
341341 {
342- debug ! ( "open_drop_for_box({:?}, {:?})" , self , ty ) ;
342+ debug ! ( "open_drop_for_box({:?}, {:?})" , self , box_ty ) ;
343343
344344 let interior = self . place . clone ( ) . deref ( ) ;
345345 let interior_path = self . elaborator . deref_subpath ( self . path ) ;
346346
347347 let succ = self . succ ; // FIXME(#6393)
348348 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) ;
350350 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 )
352352 } ) ;
353353
354354 self . drop_subpath ( & interior, interior_path, succ, unwind_succ)
@@ -788,7 +788,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
788788 self . open_drop_for_tuple ( tys)
789789 }
790790 ty:: TyAdt ( def, _) if def. is_box ( ) => {
791- self . open_drop_for_box ( ty. boxed_ty ( ) )
791+ self . open_drop_for_box ( ty)
792792 }
793793 ty:: TyAdt ( def, substs) => {
794794 self . open_drop_for_adt ( def, substs)
@@ -854,28 +854,39 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
854854
855855 fn box_free_block < ' a > (
856856 & mut self ,
857- ty : Ty < ' tcx > ,
857+ box_ty : Ty < ' tcx > ,
858858 target : BasicBlock ,
859859 unwind : Unwind ,
860860 ) -> BasicBlock {
861- let block = self . unelaborated_free_block ( ty , target, unwind) ;
861+ let block = self . unelaborated_free_block ( box_ty , target, unwind) ;
862862 self . drop_flag_test_block ( block, target, unwind)
863863 }
864864
865865 fn unelaborated_free_block < ' a > (
866866 & mut self ,
867- ty : Ty < ' tcx > ,
867+ box_ty : Ty < ' tcx > ,
868868 target : BasicBlock ,
869869 unwind : Unwind
870870 ) -> BasicBlock {
871871 let tcx = self . tcx ( ) ;
872872 let unit_temp = Place :: Local ( self . new_temp ( tcx. mk_nil ( ) ) ) ;
873873 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+ } ;
875886
876887 let call = TerminatorKind :: Call {
877888 func : Operand :: function_handle ( tcx, free_func, substs, self . source_info . span ) ,
878- args : vec ! [ Operand :: Move ( self . place . clone ( ) ) ] ,
889+ args,
879890 destination : Some ( ( unit_temp, target) ) ,
880891 cleanup : None
881892 } ; // FIXME(#6393)
0 commit comments