11use std:: { fmt, iter} ;
22
33use rustc_hir:: lang_items:: LangItem ;
4+ use rustc_hir:: UnsafeBinderCastKind ;
45use rustc_index:: Idx ;
56use rustc_middle:: mir:: patch:: MirPatch ;
67use rustc_middle:: mir:: * ;
@@ -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 ) ]
@@ -853,7 +859,7 @@ where
853859 /// ADT, both in the success case or if one of the destructors fail.
854860 fn open_drop ( & mut self ) -> BasicBlock {
855861 let ty = self . place_ty ( self . place ) ;
856- match ty. kind ( ) {
862+ match * ty. kind ( ) {
857863 ty:: Closure ( _, args) => self . open_drop_for_tuple ( args. as_closure ( ) . upvar_tys ( ) ) ,
858864 ty:: CoroutineClosure ( _, args) => {
859865 self . open_drop_for_tuple ( args. as_coroutine_closure ( ) . upvar_tys ( ) )
@@ -866,13 +872,26 @@ where
866872 // See librustc_body/transform/coroutine.rs for more details.
867873 ty:: Coroutine ( _, args) => self . open_drop_for_tuple ( args. as_coroutine ( ) . upvar_tys ( ) ) ,
868874 ty:: Tuple ( fields) => self . open_drop_for_tuple ( fields) ,
869- ty:: Adt ( def, args) => self . open_drop_for_adt ( * def, args) ,
875+ ty:: Adt ( def, args) => self . open_drop_for_adt ( def, args) ,
870876 ty:: Dynamic ( ..) => self . complete_drop ( self . succ , self . unwind ) ,
871877 ty:: Array ( ety, size) => {
872878 let size = size. try_eval_target_usize ( self . tcx ( ) , self . elaborator . param_env ( ) ) ;
873- self . open_drop_for_array ( * ety, size)
879+ self . open_drop_for_array ( ety, size)
880+ }
881+ ty:: Slice ( ety) => self . drop_loop_pair ( ety) ,
882+ ty:: UnsafeBinder ( binder) => {
883+ let ty = self . tcx ( ) . instantiate_bound_regions_with_erased ( binder. into ( ) ) ;
884+ let fields = vec ! [ (
885+ self . place. project_deeper(
886+ & [ ProjectionElem :: UnsafeBinderCast ( UnsafeBinderCastKind :: Unwrap , ty) ] ,
887+ self . tcx( ) ,
888+ ) ,
889+ self . elaborator. unsafe_binder_subpath( self . path) ,
890+ ) ] ;
891+
892+ let ( succ, unwind) = self . drop_ladder_bottom ( ) ;
893+ self . drop_ladder ( fields, succ, unwind) . 0
874894 }
875- ty:: Slice ( ety) => self . drop_loop_pair ( * ety) ,
876895
877896 _ => span_bug ! ( self . source_info. span, "open drop from non-ADT `{:?}`" , ty) ,
878897 }
0 commit comments