@@ -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 , Unnormalized } ;
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
@@ -999,22 +1000,51 @@ where
9991000 debug ! ( "destructor_call_block_sync({:?}, {:?})" , self , succ) ;
10001001 let tcx = self . tcx ( ) ;
10011002 let drop_trait = tcx. require_lang_item ( LangItem :: Drop , DUMMY_SP ) ;
1002- let drop_fn = tcx. associated_item_def_ids ( drop_trait) [ 0 ] ;
1003+ let mut drop_fn = tcx. associated_item_def_ids ( drop_trait) [ 0 ] ;
10031004 let ty = self . place_ty ( self . place ) ;
10041005
10051006 let ref_ty = Ty :: new_mut_ref ( tcx, tcx. lifetimes . re_erased , ty) ;
10061007 let ref_place = self . new_temp ( ref_ty) ;
10071008 let unit_temp = Place :: from ( self . new_temp ( tcx. types . unit ) ) ;
10081009
1009- let result = BasicBlockData :: new_stmts (
1010- vec ! [ self . assign(
1011- Place :: from( ref_place) ,
1012- Rvalue :: Ref (
1013- tcx. lifetimes. re_erased,
1014- BorrowKind :: Mut { kind: MutBorrowKind :: Default } ,
1015- self . place,
1010+ let mut arg_place = ref_place;
1011+
1012+ let mut stmts = vec ! [ self . assign(
1013+ Place :: from( ref_place) ,
1014+ Rvalue :: Ref (
1015+ tcx. lifetimes. re_erased,
1016+ BorrowKind :: Mut { kind: MutBorrowKind :: Default } ,
1017+ self . place,
1018+ ) ,
1019+ ) ] ;
1020+
1021+ // When the type implements `Drop::pin_drop`, we call it directly instead of `Drop::drop`.
1022+ if let Some ( adt) = ty. ty_adt_def ( )
1023+ && let Some ( dtor) = adt. destructor ( tcx)
1024+ && tcx. item_name ( dtor. did ) == sym:: pin_drop
1025+ {
1026+ debug ! ( "call `pin_drop` for {adt:?}" ) ;
1027+ let pin_ref_ty = Ty :: new_pinned_ref ( tcx, tcx. lifetimes . re_erased , ty, Mutability :: Mut ) ;
1028+ let pin_ref_place = self . new_temp ( pin_ref_ty) ;
1029+ stmts. push ( self . assign (
1030+ Place :: from ( pin_ref_place) ,
1031+ Rvalue :: Aggregate (
1032+ Box :: new ( AggregateKind :: Adt (
1033+ tcx. require_lang_item ( LangItem :: Pin , DUMMY_SP ) ,
1034+ VariantIdx :: ZERO ,
1035+ tcx. mk_args ( & [ ref_ty. into ( ) ] ) ,
1036+ None ,
1037+ None ,
1038+ ) ) ,
1039+ [ Operand :: Move ( Place :: from ( ref_place) ) ] . into ( ) ,
10161040 ) ,
1017- ) ] ,
1041+ ) ) ;
1042+ drop_fn = tcx. associated_item_def_ids ( drop_trait) [ 1 ] ;
1043+ arg_place = pin_ref_place;
1044+ }
1045+
1046+ let result = BasicBlockData :: new_stmts (
1047+ stmts,
10181048 Some ( Terminator {
10191049 kind : TerminatorKind :: Call {
10201050 func : Operand :: function_handle (
@@ -1023,7 +1053,7 @@ where
10231053 [ ty. into ( ) ] ,
10241054 self . source_info . span ,
10251055 ) ,
1026- args : [ Spanned { node : Operand :: Move ( Place :: from ( ref_place ) ) , span : DUMMY_SP } ]
1056+ args : [ Spanned { node : Operand :: Move ( Place :: from ( arg_place ) ) , span : DUMMY_SP } ]
10271057 . into ( ) ,
10281058 destination : unit_temp,
10291059 target : Some ( succ) ,
0 commit comments