@@ -9,6 +9,7 @@ use rustc_middle::ty::adjustment::PointerCoercion;
99use rustc_middle:: ty:: util:: IntTypeExt ;
1010use rustc_middle:: ty:: { self , GenericArg , GenericArgsRef , Ty , TyCtxt } ;
1111use rustc_middle:: { bug, span_bug, traits} ;
12+ use rustc_span:: symbol:: sym;
1213use rustc_span:: { DUMMY_SP , Spanned , dummy_spanned} ;
1314use tracing:: { debug, instrument} ;
1415
@@ -973,26 +974,55 @@ where
973974 fn destructor_call_block_sync ( & mut self , succ : BasicBlock , unwind : Unwind ) -> BasicBlock {
974975 let tcx = self . tcx ( ) ;
975976 let drop_trait = tcx. require_lang_item ( LangItem :: Drop , DUMMY_SP ) ;
976- let drop_fn = tcx. associated_item_def_ids ( drop_trait) [ 0 ] ;
977+ let mut drop_fn = tcx. associated_item_def_ids ( drop_trait) [ 0 ] ;
977978 let ty = self . place_ty ( self . place ) ;
978979
979980 let ref_ty = Ty :: new_mut_ref ( tcx, tcx. lifetimes . re_erased , ty) ;
980981 let ref_place = self . new_temp ( ref_ty) ;
981982 let unit_temp = Place :: from ( self . new_temp ( tcx. types . unit ) ) ;
982983
984+ let mut arg_place = ref_place;
985+
986+ let mut stmts = vec ! [ self . assign(
987+ Place :: from( ref_place) ,
988+ Rvalue :: Ref (
989+ tcx. lifetimes. re_erased,
990+ BorrowKind :: Mut { kind: MutBorrowKind :: Default } ,
991+ self . place,
992+ ) ,
993+ ) ] ;
994+
995+ // When the type implements `Drop::pin_drop`, we call it directly instead of `Drop::drop`.
996+ if let Some ( adt) = ty. ty_adt_def ( )
997+ && let Some ( dtor) = adt. destructor ( tcx)
998+ && tcx. item_name ( dtor. did ) == sym:: pin_drop
999+ {
1000+ debug ! ( "call `pin_drop` for {adt:?}" ) ;
1001+ let pin_ref_ty = Ty :: new_pinned_ref ( tcx, tcx. lifetimes . re_erased , ty, Mutability :: Mut ) ;
1002+ let pin_ref_place = self . new_temp ( pin_ref_ty) ;
1003+ stmts. push ( self . assign (
1004+ Place :: from ( pin_ref_place) ,
1005+ Rvalue :: Aggregate (
1006+ Box :: new ( AggregateKind :: Adt (
1007+ tcx. require_lang_item ( LangItem :: Pin , DUMMY_SP ) ,
1008+ VariantIdx :: ZERO ,
1009+ tcx. mk_args ( & [ ref_ty. into ( ) ] ) ,
1010+ None ,
1011+ None ,
1012+ ) ) ,
1013+ [ Operand :: Move ( Place :: from ( ref_place) ) ] . into ( ) ,
1014+ ) ,
1015+ ) ) ;
1016+ drop_fn = tcx. associated_item_def_ids ( drop_trait) [ 1 ] ;
1017+ arg_place = pin_ref_place;
1018+ }
1019+
9831020 self . new_block_with_statements (
9841021 unwind,
985- vec ! [ self . assign(
986- Place :: from( ref_place) ,
987- Rvalue :: Ref (
988- tcx. lifetimes. re_erased,
989- BorrowKind :: Mut { kind: MutBorrowKind :: Default } ,
990- self . place,
991- ) ,
992- ) ] ,
1022+ stmts,
9931023 TerminatorKind :: Call {
9941024 func : Operand :: function_handle ( tcx, drop_fn, [ ty. into ( ) ] , self . source_info . span ) ,
995- args : [ Spanned { node : Operand :: Move ( Place :: from ( ref_place ) ) , span : DUMMY_SP } ]
1025+ args : [ Spanned { node : Operand :: Move ( Place :: from ( arg_place ) ) , span : DUMMY_SP } ]
9961026 . into ( ) ,
9971027 destination : unit_temp,
9981028 target : Some ( succ) ,
0 commit comments