@@ -10,7 +10,7 @@ use rustc_index::{IndexVec, indexvec};
1010use rustc_middle:: mir:: visit:: MutVisitor ;
1111use rustc_middle:: mir:: * ;
1212use rustc_middle:: span_bug;
13- use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
13+ use rustc_middle:: ty:: { self , PatternKind , Ty , TyCtxt } ;
1414
1515use crate :: patch:: MirPatch ;
1616
@@ -20,21 +20,27 @@ fn build_ptr_tys<'tcx>(
2020 pointee : Ty < ' tcx > ,
2121 unique_def : ty:: AdtDef < ' tcx > ,
2222 nonnull_def : ty:: AdtDef < ' tcx > ,
23- ) -> ( Ty < ' tcx > , Ty < ' tcx > , Ty < ' tcx > ) {
23+ ) -> ( Ty < ' tcx > , Ty < ' tcx > , Ty < ' tcx > , Ty < ' tcx > ) {
2424 let args = tcx. mk_args ( & [ pointee. into ( ) ] ) ;
2525 let unique_ty = Ty :: new_adt ( tcx, unique_def, args) ;
2626 let nonnull_ty = Ty :: new_adt ( tcx, nonnull_def, args) ;
2727 let ptr_ty = Ty :: new_imm_ptr ( tcx, pointee) ;
28+ let pat_ty = Ty :: new_pat ( tcx, ptr_ty, tcx. mk_pat ( PatternKind :: NotNull ) ) ;
2829
29- ( unique_ty, nonnull_ty, ptr_ty)
30+ ( unique_ty, nonnull_ty, pat_ty , ptr_ty)
3031}
3132
3233/// Constructs the projection needed to access a Box's pointer
3334pub ( super ) fn build_projection < ' tcx > (
3435 unique_ty : Ty < ' tcx > ,
3536 nonnull_ty : Ty < ' tcx > ,
36- ) -> [ PlaceElem < ' tcx > ; 2 ] {
37- [ PlaceElem :: Field ( FieldIdx :: ZERO , unique_ty) , PlaceElem :: Field ( FieldIdx :: ZERO , nonnull_ty) ]
37+ pat_ty : Ty < ' tcx > ,
38+ ) -> [ PlaceElem < ' tcx > ; 3 ] {
39+ [
40+ PlaceElem :: Field ( FieldIdx :: ZERO , unique_ty) ,
41+ PlaceElem :: Field ( FieldIdx :: ZERO , nonnull_ty) ,
42+ PlaceElem :: Field ( FieldIdx :: ZERO , pat_ty) ,
43+ ]
3844}
3945
4046struct ElaborateBoxDerefVisitor < ' a , ' tcx > {
@@ -66,7 +72,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'a, 'tcx> {
6672 {
6773 let source_info = self . local_decls [ place. local ] . source_info ;
6874
69- let ( unique_ty, nonnull_ty, ptr_ty) =
75+ let ( unique_ty, nonnull_ty, pat_ty , ptr_ty) =
7076 build_ptr_tys ( tcx, boxed_ty, self . unique_def , self . nonnull_def ) ;
7177
7278 let ptr_local = self . patch . new_temp ( ptr_ty, source_info. span ) ;
@@ -78,7 +84,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'a, 'tcx> {
7884 CastKind :: Transmute ,
7985 Operand :: Copy (
8086 Place :: from ( place. local )
81- . project_deeper ( & build_projection ( unique_ty, nonnull_ty) , tcx) ,
87+ . project_deeper ( & build_projection ( unique_ty, nonnull_ty, pat_ty ) , tcx) ,
8288 ) ,
8389 ptr_ty,
8490 ) ,
@@ -101,7 +107,9 @@ impl<'a, 'tcx> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'a, 'tcx> {
101107 && let ty:: Adt ( box_adt, box_args) = Ty :: new_box ( tcx, pointee) . kind ( )
102108 {
103109 let args = tcx. mk_args ( & [ pointee. into ( ) ] ) ;
104- let ( unique_ty, nonnull_ty, ptr_ty) =
110+ // We skip the pointer type by directly transmuting from the `*const u8` of
111+ // `ShallowInitBox` to the pattern type that will get placed inside `NonNull`
112+ let ( unique_ty, nonnull_ty, pat_ty, _ptr_ty) =
105113 build_ptr_tys ( tcx, pointee, self . unique_def , self . nonnull_def ) ;
106114 let adt_kind = |def : ty:: AdtDef < ' tcx > , args| {
107115 Box :: new ( AggregateKind :: Adt ( def. did ( ) , VariantIdx :: ZERO , args, None , None ) )
@@ -114,11 +122,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'a, 'tcx> {
114122 } ) )
115123 } ;
116124
117- let constptr = self . patch . new_temp ( ptr_ty , source_info. span ) ;
125+ let constptr = self . patch . new_temp ( pat_ty , source_info. span ) ;
118126 self . patch . add_assign (
119127 location,
120128 constptr. into ( ) ,
121- Rvalue :: Cast ( CastKind :: Transmute , mutptr_to_u8. clone ( ) , ptr_ty ) ,
129+ Rvalue :: Cast ( CastKind :: Transmute , mutptr_to_u8. clone ( ) , pat_ty ) ,
122130 ) ;
123131
124132 let nonnull = self . patch . new_temp ( nonnull_ty, source_info. span ) ;
@@ -199,10 +207,11 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs {
199207 let new_projections =
200208 new_projections. get_or_insert_with ( || base. projection . to_vec ( ) ) ;
201209
202- let ( unique_ty, nonnull_ty, ptr_ty) =
210+ let ( unique_ty, nonnull_ty, pat_ty , ptr_ty) =
203211 build_ptr_tys ( tcx, boxed_ty, unique_def, nonnull_def) ;
204212
205- new_projections. extend_from_slice ( & build_projection ( unique_ty, nonnull_ty) ) ;
213+ new_projections
214+ . extend_from_slice ( & build_projection ( unique_ty, nonnull_ty, pat_ty) ) ;
206215 // While we can't project into `NonNull<_>` in a basic block
207216 // due to MCP#807, this is debug info where it's fine.
208217 new_projections. push ( PlaceElem :: Field ( FieldIdx :: ZERO , ptr_ty) ) ;
0 commit comments