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