@@ -9,7 +9,35 @@ use rustc_middle::mir::patch::MirPatch;
9
9
use rustc_middle:: mir:: visit:: MutVisitor ;
10
10
use rustc_middle:: mir:: * ;
11
11
use 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
+ }
13
41
14
42
struct ElaborateBoxDerefVisitor < ' tcx , ' a > {
15
43
tcx : TyCtxt < ' tcx > ,
@@ -38,10 +66,8 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
38
66
if place. projection . first ( ) == Some ( & PlaceElem :: Deref ) && base_ty. is_box ( ) {
39
67
let source_info = self . local_decls [ place. local ] . source_info ;
40
68
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 ) ;
45
71
46
72
let ptr_local = self . patch . new_temp ( ptr_ty, source_info. span ) ;
47
73
self . local_decls . push ( LocalDecl :: new ( ptr_ty, source_info. span ) ) ;
@@ -51,14 +77,10 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
51
77
self . patch . add_assign (
52
78
location,
53
79
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
+ ) ) ,
62
84
) ;
63
85
64
86
place. local = ptr_local;
0 commit comments