@@ -3,7 +3,7 @@ use syntax::ast;
33use syntax:: symbol:: sym;
44use syntax_pos:: Span ;
55
6- use rustc:: ty:: { self , TyCtxt } ;
6+ use rustc:: ty:: { self , TyCtxt , Ty } ;
77use rustc:: hir:: def_id:: DefId ;
88use rustc:: mir:: { self , Body , Location , Local } ;
99use rustc_data_structures:: bit_set:: BitSet ;
@@ -114,15 +114,20 @@ pub fn sanity_check_via_rustc_peek<'tcx, O>(
114114 . expect ( "call to rustc_peek should be preceded by \
115115 assignment to temporary holding its argument") ;
116116
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+ }
120125
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+ }
126131 }
127132 }
128133}
@@ -144,9 +149,26 @@ fn value_assigned_to_local<'a, 'tcx>(
144149 None
145150}
146151
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+
147168#[ derive( Clone , Copy , Debug ) ]
148169pub struct PeekCall {
149170 arg : Local ,
171+ kind : PeekCallKind ,
150172 span : Span ,
151173}
152174
@@ -159,14 +181,15 @@ impl PeekCall {
159181 if let mir:: TerminatorKind :: Call { func : mir:: Operand :: Constant ( func) , args, .. } =
160182 & terminator. kind
161183 {
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) ;
164186 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 {
166188 return None ;
167189 }
168190
169191 assert_eq ! ( args. len( ) , 1 ) ;
192+ let kind = PeekCallKind :: from_arg_ty ( substs. type_at ( 0 ) ) ;
170193 let arg = match args[ 0 ] {
171194 | mir:: Operand :: Copy ( mir:: Place :: Base ( mir:: PlaceBase :: Local ( local) ) )
172195 | mir:: Operand :: Move ( mir:: Place :: Base ( mir:: PlaceBase :: Local ( local) ) )
@@ -181,6 +204,7 @@ impl PeekCall {
181204
182205 return Some ( PeekCall {
183206 arg,
207+ kind,
184208 span,
185209 } ) ;
186210 }
0 commit comments