10
10
11
11
use hir:: def:: Def ;
12
12
use hir:: def_id:: DefId ;
13
- use infer:: InferCtxt ;
14
13
use ty:: { self , Ty , TyCtxt } ;
15
14
use ty:: layout:: { LayoutError , Pointer , SizeSkeleton } ;
16
15
@@ -30,8 +29,10 @@ struct ItemVisitor<'a, 'tcx: 'a> {
30
29
tcx : TyCtxt < ' a , ' tcx , ' tcx >
31
30
}
32
31
33
- struct ExprVisitor < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
34
- infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx >
32
+ struct ExprVisitor < ' a , ' tcx : ' a > {
33
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
34
+ tables : & ' tcx ty:: TypeckTables < ' tcx > ,
35
+ param_env : ty:: ParamEnv < ' tcx > ,
35
36
}
36
37
37
38
/// If the type is `Option<T>`, it will return `T`, otherwise
@@ -63,18 +64,18 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
63
64
ty
64
65
}
65
66
66
- impl < ' a , ' gcx , ' tcx > ExprVisitor < ' a , ' gcx , ' tcx > {
67
+ impl < ' a , ' tcx > ExprVisitor < ' a , ' tcx > {
67
68
fn def_id_is_transmute ( & self , def_id : DefId ) -> bool {
68
- let intrinsic = match self . infcx . tcx . type_of ( def_id) . sty {
69
+ let intrinsic = match self . tcx . type_of ( def_id) . sty {
69
70
ty:: TyFnDef ( .., bfty) => bfty. abi ( ) == RustIntrinsic ,
70
71
_ => return false
71
72
} ;
72
- intrinsic && self . infcx . tcx . item_name ( def_id) == "transmute"
73
+ intrinsic && self . tcx . item_name ( def_id) == "transmute"
73
74
}
74
75
75
- fn check_transmute ( & self , span : Span , from : Ty < ' gcx > , to : Ty < ' gcx > ) {
76
- let sk_from = SizeSkeleton :: compute ( from, self . infcx ) ;
77
- let sk_to = SizeSkeleton :: compute ( to, self . infcx ) ;
76
+ fn check_transmute ( & self , span : Span , from : Ty < ' tcx > , to : Ty < ' tcx > ) {
77
+ let sk_from = SizeSkeleton :: compute ( from, self . tcx , self . param_env ) ;
78
+ let sk_to = SizeSkeleton :: compute ( to, self . tcx , self . param_env ) ;
78
79
79
80
// Check for same size using the skeletons.
80
81
if let ( Ok ( sk_from) , Ok ( sk_to) ) = ( sk_from, sk_to) {
@@ -84,11 +85,11 @@ impl<'a, 'gcx, 'tcx> ExprVisitor<'a, 'gcx, 'tcx> {
84
85
85
86
// Special-case transmutting from `typeof(function)` and
86
87
// `Option<typeof(function)>` to present a clearer error.
87
- let from = unpack_option_like ( self . infcx . tcx . global_tcx ( ) , from) ;
88
+ let from = unpack_option_like ( self . tcx . global_tcx ( ) , from) ;
88
89
match ( & from. sty , sk_to) {
89
90
( & ty:: TyFnDef ( ..) , SizeSkeleton :: Known ( size_to) )
90
- if size_to == Pointer . size ( self . infcx ) => {
91
- struct_span_err ! ( self . infcx . tcx. sess, span, E0591 ,
91
+ if size_to == Pointer . size ( self . tcx ) => {
92
+ struct_span_err ! ( self . tcx. sess, span, E0591 ,
92
93
"`{}` is zero-sized and can't be transmuted to `{}`" ,
93
94
from, to)
94
95
. span_note ( span, "cast with `as` to a pointer instead" )
@@ -100,7 +101,7 @@ impl<'a, 'gcx, 'tcx> ExprVisitor<'a, 'gcx, 'tcx> {
100
101
}
101
102
102
103
// Try to display a sensible error with as much information as possible.
103
- let skeleton_string = |ty : Ty < ' gcx > , sk| {
104
+ let skeleton_string = |ty : Ty < ' tcx > , sk| {
104
105
match sk {
105
106
Ok ( SizeSkeleton :: Known ( size) ) => {
106
107
format ! ( "{} bits" , size. bits( ) )
@@ -119,7 +120,7 @@ impl<'a, 'gcx, 'tcx> ExprVisitor<'a, 'gcx, 'tcx> {
119
120
}
120
121
} ;
121
122
122
- struct_span_err ! ( self . infcx . tcx. sess, span, E0512 ,
123
+ struct_span_err ! ( self . tcx. sess, span, E0512 ,
123
124
"transmute called with differently sized types: \
124
125
{} ({}) to {} ({})",
125
126
from, skeleton_string( from, sk_from) ,
@@ -138,32 +139,30 @@ impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> {
138
139
}
139
140
140
141
fn visit_nested_body ( & mut self , body_id : hir:: BodyId ) {
142
+ let owner_def_id = self . tcx . hir . body_owner_def_id ( body_id) ;
141
143
let body = self . tcx . hir . body ( body_id) ;
142
- self . tcx . infer_ctxt ( body_id) . enter ( |infcx| {
143
- let mut visitor = ExprVisitor {
144
- infcx : & infcx
145
- } ;
146
- visitor. visit_body ( body) ;
147
- } ) ;
144
+ let param_env = self . tcx . param_env ( owner_def_id) ;
145
+ let tables = self . tcx . typeck_tables_of ( owner_def_id) ;
146
+ ExprVisitor { tcx : self . tcx , param_env, tables } . visit_body ( body) ;
148
147
self . visit_body ( body) ;
149
148
}
150
149
}
151
150
152
- impl < ' a , ' gcx , ' tcx > Visitor < ' gcx > for ExprVisitor < ' a , ' gcx , ' tcx > {
153
- fn nested_visit_map < ' this > ( & ' this mut self ) -> NestedVisitorMap < ' this , ' gcx > {
151
+ impl < ' a , ' tcx > Visitor < ' tcx > for ExprVisitor < ' a , ' tcx > {
152
+ fn nested_visit_map < ' this > ( & ' this mut self ) -> NestedVisitorMap < ' this , ' tcx > {
154
153
NestedVisitorMap :: None
155
154
}
156
155
157
- fn visit_expr ( & mut self , expr : & ' gcx hir:: Expr ) {
156
+ fn visit_expr ( & mut self , expr : & ' tcx hir:: Expr ) {
158
157
let def = if let hir:: ExprPath ( ref qpath) = expr. node {
159
- self . infcx . tables . borrow ( ) . qpath_def ( qpath, expr. id )
158
+ self . tables . qpath_def ( qpath, expr. id )
160
159
} else {
161
160
Def :: Err
162
161
} ;
163
162
match def {
164
163
Def :: Fn ( did) if self . def_id_is_transmute ( did) => {
165
- let typ = self . infcx . tables . borrow ( ) . node_id_to_type ( expr. id ) ;
166
- let typ = self . infcx . tcx . lift_to_global ( & typ) . unwrap ( ) ;
164
+ let typ = self . tables . node_id_to_type ( expr. id ) ;
165
+ let typ = self . tcx . lift_to_global ( & typ) . unwrap ( ) ;
167
166
match typ. sty {
168
167
ty:: TyFnDef ( .., sig) if sig. abi ( ) == RustIntrinsic => {
169
168
let from = sig. inputs ( ) . skip_binder ( ) [ 0 ] ;
0 commit comments