@@ -3,7 +3,7 @@ use syntax::ast;
3
3
use syntax:: symbol:: sym;
4
4
use syntax_pos:: Span ;
5
5
6
- use rustc:: ty:: { self , TyCtxt } ;
6
+ use rustc:: ty:: { self , TyCtxt , Ty } ;
7
7
use rustc:: hir:: def_id:: DefId ;
8
8
use rustc:: mir:: { self , Body , Location , Local } ;
9
9
use rustc_data_structures:: bit_set:: BitSet ;
@@ -114,15 +114,20 @@ pub fn sanity_check_via_rustc_peek<'tcx, O>(
114
114
. expect ( "call to rustc_peek should be preceded by \
115
115
assignment to temporary holding its argument") ;
116
116
117
- if let mir:: Rvalue :: Ref ( _, mir:: BorrowKind :: Shared , peeking_at_place) = peek_rval {
118
- let loc = Location { block : bb, statement_index } ;
119
- let flow_state = dataflow:: state_for_location ( loc, results. operator ( ) , results, body) ;
117
+ match ( call. kind , peek_rval) {
118
+ | ( PeekCallKind :: ByRef , mir:: Rvalue :: Ref ( _, _, peek_at) )
119
+ | ( PeekCallKind :: ByVal , mir:: Rvalue :: Use ( mir:: Operand :: Move ( peek_at) ) )
120
+ | ( PeekCallKind :: ByVal , mir:: Rvalue :: Use ( mir:: Operand :: Copy ( peek_at) ) )
121
+ => {
122
+ let loc = Location { block : bb, statement_index } ;
123
+ results. peek_at ( tcx, body, peek_at, loc, call) ;
124
+ }
120
125
121
- results . operator ( ) . peek_at ( tcx , peeking_at_place , & flow_state , call ) ;
122
- } else {
123
- let msg = "rustc_peek: argument expression \
124
- must be immediate borrow of form `&expr`" ;
125
- tcx . sess . span_err ( call . span , msg ) ;
126
+ _ => {
127
+ let msg = "rustc_peek: argument expression \
128
+ must be either `place` or `&place`" ;
129
+ tcx . sess . span_err ( call . span , msg ) ;
130
+ }
126
131
}
127
132
}
128
133
}
@@ -144,9 +149,26 @@ fn value_assigned_to_local<'a, 'tcx>(
144
149
None
145
150
}
146
151
152
+ #[ derive( Clone , Copy , Debug ) ]
153
+ enum PeekCallKind {
154
+ ByVal ,
155
+ ByRef ,
156
+ }
157
+
158
+ impl PeekCallKind {
159
+ fn from_arg_ty ( arg : Ty < ' _ > ) -> Self {
160
+ if let ty:: Ref ( _, _, _) = arg. sty {
161
+ PeekCallKind :: ByRef
162
+ } else {
163
+ PeekCallKind :: ByVal
164
+ }
165
+ }
166
+ }
167
+
147
168
#[ derive( Clone , Copy , Debug ) ]
148
169
pub struct PeekCall {
149
170
arg : Local ,
171
+ kind : PeekCallKind ,
150
172
span : Span ,
151
173
}
152
174
@@ -159,14 +181,15 @@ impl PeekCall {
159
181
if let mir:: TerminatorKind :: Call { func : mir:: Operand :: Constant ( func) , args, .. } =
160
182
& terminator. kind
161
183
{
162
- if let ty:: FnDef ( def_id, _ ) = func. ty . sty {
163
- let abi = tcx. fn_sig ( def_id) . abi ( ) ;
184
+ if let ty:: FnDef ( def_id, substs ) = func. ty . sty {
185
+ let sig = tcx. fn_sig ( def_id) ;
164
186
let name = tcx. item_name ( def_id) ;
165
- if abi != Abi :: RustIntrinsic || name != sym:: rustc_peek {
187
+ if sig . abi ( ) != Abi :: RustIntrinsic || name != sym:: rustc_peek {
166
188
return None ;
167
189
}
168
190
169
191
assert_eq ! ( args. len( ) , 1 ) ;
192
+ let kind = PeekCallKind :: from_arg_ty ( substs. type_at ( 0 ) ) ;
170
193
let arg = match args[ 0 ] {
171
194
| mir:: Operand :: Copy ( mir:: Place :: Base ( mir:: PlaceBase :: Local ( local) ) )
172
195
| mir:: Operand :: Move ( mir:: Place :: Base ( mir:: PlaceBase :: Local ( local) ) )
@@ -181,6 +204,7 @@ impl PeekCall {
181
204
182
205
return Some ( PeekCall {
183
206
arg,
207
+ kind,
184
208
span,
185
209
} ) ;
186
210
}
0 commit comments