11use std:: { fmt, iter} ;
22
33use rustc_abi:: { FIRST_VARIANT , FieldIdx , VariantIdx } ;
4+ use rustc_hir:: UnsafeBinderCastKind ;
45use rustc_hir:: lang_items:: LangItem ;
56use rustc_index:: Idx ;
67use rustc_middle:: mir:: patch:: MirPatch ;
@@ -151,6 +152,11 @@ pub trait DropElaborator<'a, 'tcx>: fmt::Debug {
151152 ///
152153 /// This is only relevant for array patterns, which can move out of individual array elements.
153154 fn array_subpath ( & self , path : Self :: Path , index : u64 , size : u64 ) -> Option < Self :: Path > ;
155+
156+ /// Returns the subpath of casting an unsafe binder.
157+ ///
158+ /// If this returns `None`, elements of `path` will not get a dedicated drop flag.
159+ fn unsafe_binder_subpath ( & self , path : Self :: Path ) -> Option < Self :: Path > ;
154160}
155161
156162#[ derive( Debug ) ]
@@ -846,7 +852,7 @@ where
846852 /// ADT, both in the success case or if one of the destructors fail.
847853 fn open_drop ( & mut self ) -> BasicBlock {
848854 let ty = self . place_ty ( self . place ) ;
849- match ty. kind ( ) {
855+ match * ty. kind ( ) {
850856 ty:: Closure ( _, args) => self . open_drop_for_tuple ( args. as_closure ( ) . upvar_tys ( ) ) ,
851857 ty:: CoroutineClosure ( _, args) => {
852858 self . open_drop_for_tuple ( args. as_coroutine_closure ( ) . upvar_tys ( ) )
@@ -859,13 +865,26 @@ where
859865 // See librustc_body/transform/coroutine.rs for more details.
860866 ty:: Coroutine ( _, args) => self . open_drop_for_tuple ( args. as_coroutine ( ) . upvar_tys ( ) ) ,
861867 ty:: Tuple ( fields) => self . open_drop_for_tuple ( fields) ,
862- ty:: Adt ( def, args) => self . open_drop_for_adt ( * def, args) ,
868+ ty:: Adt ( def, args) => self . open_drop_for_adt ( def, args) ,
863869 ty:: Dynamic ( ..) => self . complete_drop ( self . succ , self . unwind ) ,
864870 ty:: Array ( ety, size) => {
865871 let size = size. try_to_target_usize ( self . tcx ( ) ) ;
866- self . open_drop_for_array ( * ety, size)
872+ self . open_drop_for_array ( ety, size)
873+ }
874+ ty:: Slice ( ety) => self . drop_loop_pair ( ety) ,
875+ ty:: UnsafeBinder ( binder) => {
876+ let ty = self . tcx ( ) . instantiate_bound_regions_with_erased ( binder. into ( ) ) ;
877+ let fields = vec ! [ (
878+ self . place. project_deeper(
879+ & [ ProjectionElem :: UnsafeBinderCast ( UnsafeBinderCastKind :: Unwrap , ty) ] ,
880+ self . tcx( ) ,
881+ ) ,
882+ self . elaborator. unsafe_binder_subpath( self . path) ,
883+ ) ] ;
884+
885+ let ( succ, unwind) = self . drop_ladder_bottom ( ) ;
886+ self . drop_ladder ( fields, succ, unwind) . 0
867887 }
868- ty:: Slice ( ety) => self . drop_loop_pair ( * ety) ,
869888
870889 _ => span_bug ! ( self . source_info. span, "open drop from non-ADT `{:?}`" , ty) ,
871890 }
0 commit comments