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