@@ -9,7 +9,35 @@ use rustc_middle::mir::patch::MirPatch;
99use rustc_middle:: mir:: visit:: MutVisitor ;
1010use rustc_middle:: mir:: * ;
1111use rustc_middle:: ty:: subst:: Subst ;
12- use rustc_middle:: ty:: TyCtxt ;
12+ use rustc_middle:: ty:: { Ty , TyCtxt } ;
13+
14+ /// Constructs the types used when accessing a Box's pointer
15+ pub fn build_ptr_tys < ' tcx > (
16+ tcx : TyCtxt < ' tcx > ,
17+ pointee : Ty < ' tcx > ,
18+ unique_did : DefId ,
19+ nonnull_did : DefId ,
20+ ) -> ( Ty < ' tcx > , Ty < ' tcx > , Ty < ' tcx > ) {
21+ let substs = tcx. intern_substs ( & [ pointee. into ( ) ] ) ;
22+ let unique_ty = tcx. bound_type_of ( unique_did) . subst ( tcx, substs) ;
23+ let nonnull_ty = tcx. bound_type_of ( nonnull_did) . subst ( tcx, substs) ;
24+ let ptr_ty = tcx. mk_imm_ptr ( pointee) ;
25+
26+ ( unique_ty, nonnull_ty, ptr_ty)
27+ }
28+
29+ // Constructs the projection needed to access a Box's pointer
30+ pub fn build_projection < ' tcx > (
31+ unique_ty : Ty < ' tcx > ,
32+ nonnull_ty : Ty < ' tcx > ,
33+ ptr_ty : Ty < ' tcx > ,
34+ ) -> [ PlaceElem < ' tcx > ; 3 ] {
35+ [
36+ PlaceElem :: Field ( Field :: new ( 0 ) , unique_ty) ,
37+ PlaceElem :: Field ( Field :: new ( 0 ) , nonnull_ty) ,
38+ PlaceElem :: Field ( Field :: new ( 0 ) , ptr_ty) ,
39+ ]
40+ }
1341
1442struct ElaborateBoxDerefVisitor < ' tcx , ' a > {
1543 tcx : TyCtxt < ' tcx > ,
@@ -38,10 +66,8 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
3866 if place. projection . first ( ) == Some ( & PlaceElem :: Deref ) && base_ty. is_box ( ) {
3967 let source_info = self . local_decls [ place. local ] . source_info ;
4068
41- let substs = tcx. intern_substs ( & [ base_ty. boxed_ty ( ) . into ( ) ] ) ;
42- let unique_ty = tcx. bound_type_of ( self . unique_did ) . subst ( tcx, substs) ;
43- let nonnull_ty = tcx. bound_type_of ( self . nonnull_did ) . subst ( tcx, substs) ;
44- let ptr_ty = tcx. mk_imm_ptr ( base_ty. boxed_ty ( ) ) ;
69+ let ( unique_ty, nonnull_ty, ptr_ty) =
70+ build_ptr_tys ( tcx, base_ty. boxed_ty ( ) , self . unique_did , self . nonnull_did ) ;
4571
4672 let ptr_local = self . patch . new_temp ( ptr_ty, source_info. span ) ;
4773 self . local_decls . push ( LocalDecl :: new ( ptr_ty, source_info. span ) ) ;
@@ -51,14 +77,10 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
5177 self . patch . add_assign (
5278 location,
5379 Place :: from ( ptr_local) ,
54- Rvalue :: Use ( Operand :: Copy ( Place :: from ( place. local ) . project_deeper (
55- & [
56- PlaceElem :: Field ( Field :: new ( 0 ) , unique_ty) ,
57- PlaceElem :: Field ( Field :: new ( 0 ) , nonnull_ty) ,
58- PlaceElem :: Field ( Field :: new ( 0 ) , ptr_ty) ,
59- ] ,
60- tcx,
61- ) ) ) ,
80+ Rvalue :: Use ( Operand :: Copy (
81+ Place :: from ( place. local )
82+ . project_deeper ( & build_projection ( unique_ty, nonnull_ty, ptr_ty) , tcx) ,
83+ ) ) ,
6284 ) ;
6385
6486 place. local = ptr_local;
0 commit comments