1
1
use std:: { fmt, iter} ;
2
2
3
+ use rustc_hir:: UnsafeBinderCastKind ;
3
4
use rustc_hir:: lang_items:: LangItem ;
4
5
use rustc_index:: Idx ;
5
6
use rustc_middle:: mir:: patch:: MirPatch ;
@@ -152,6 +153,11 @@ pub trait DropElaborator<'a, 'tcx>: fmt::Debug {
152
153
///
153
154
/// This is only relevant for array patterns, which can move out of individual array elements.
154
155
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 > ;
155
161
}
156
162
157
163
#[ derive( Debug ) ]
@@ -847,7 +853,7 @@ where
847
853
/// ADT, both in the success case or if one of the destructors fail.
848
854
fn open_drop ( & mut self ) -> BasicBlock {
849
855
let ty = self . place_ty ( self . place ) ;
850
- match ty. kind ( ) {
856
+ match * ty. kind ( ) {
851
857
ty:: Closure ( _, args) => self . open_drop_for_tuple ( args. as_closure ( ) . upvar_tys ( ) ) ,
852
858
ty:: CoroutineClosure ( _, args) => {
853
859
self . open_drop_for_tuple ( args. as_coroutine_closure ( ) . upvar_tys ( ) )
@@ -860,13 +866,26 @@ where
860
866
// See librustc_body/transform/coroutine.rs for more details.
861
867
ty:: Coroutine ( _, args) => self . open_drop_for_tuple ( args. as_coroutine ( ) . upvar_tys ( ) ) ,
862
868
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) ,
864
870
ty:: Dynamic ( ..) => self . complete_drop ( self . succ , self . unwind ) ,
865
871
ty:: Array ( ety, size) => {
866
872
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
868
888
}
869
- ty:: Slice ( ety) => self . drop_loop_pair ( * ety) ,
870
889
871
890
_ => span_bug ! ( self . source_info. span, "open drop from non-ADT `{:?}`" , ty) ,
872
891
}
0 commit comments