@@ -15,15 +15,17 @@ use std::mem;
1515use rustc:: hir:: def_id:: DefId ;
1616use rustc:: hir:: def:: Def ;
1717use rustc:: hir:: map:: definitions:: DefPathData ;
18+ use rustc:: ich:: { StableHashingContext , StableHashingContextProvider } ;
1819use rustc:: mir;
1920use rustc:: ty:: layout:: {
2021 self , Size , Align , HasDataLayout , LayoutOf , TyLayout
2122} ;
2223use rustc:: ty:: subst:: { Subst , Substs } ;
2324use rustc:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
2425use rustc:: ty:: query:: TyCtxtAt ;
25- use rustc_data_structures:: fx:: { FxHashSet , FxHasher } ;
26+ use rustc_data_structures:: fx:: FxHashSet ;
2627use rustc_data_structures:: indexed_vec:: IndexVec ;
28+ use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher , StableHasherResult } ;
2729use rustc:: mir:: interpret:: {
2830 GlobalId , Scalar , FrameInfo ,
2931 EvalResult , EvalErrorKind ,
@@ -134,25 +136,21 @@ impl<'mir, 'tcx: 'mir> PartialEq for Frame<'mir, 'tcx> {
134136 }
135137}
136138
137- impl < ' mir , ' tcx : ' mir > Hash for Frame < ' mir , ' tcx > {
138- fn hash < H : Hasher > ( & self , state : & mut H ) {
139+ impl < ' a , ' mir , ' tcx : ' mir > HashStable < StableHashingContext < ' a > > for Frame < ' mir , ' tcx > {
140+ fn hash_stable < W : StableHasherResult > ( & self , hcx : & mut StableHashingContext < ' a > , hasher : & mut StableHasher < W > ) {
139141 let Frame {
140- mir : _ ,
142+ mir,
141143 instance,
142- span : _ ,
144+ span,
143145 return_to_block,
144146 return_place,
145147 locals,
146148 block,
147149 stmt,
148150 } = self ;
149151
150- instance. hash ( state) ;
151- return_to_block. hash ( state) ;
152- return_place. hash ( state) ;
153- locals. hash ( state) ;
154- block. hash ( state) ;
155- stmt. hash ( state) ;
152+ ( mir, instance, span, return_to_block) . hash_stable ( hcx, hasher) ;
153+ ( return_place, locals, block, stmt) . hash_stable ( hcx, hasher) ;
156154 }
157155}
158156
@@ -168,6 +166,15 @@ pub enum StackPopCleanup {
168166 None { cleanup : bool } ,
169167}
170168
169+ impl < ' a > HashStable < StableHashingContext < ' a > > for StackPopCleanup {
170+ fn hash_stable < W : StableHasherResult > ( & self , hcx : & mut StableHashingContext < ' b > , hasher : & mut StableHasher < W > ) {
171+ match self {
172+ StackPopCleanup :: Goto ( ref block) => block. hash_stable ( hcx, hasher) ,
173+ StackPopCleanup :: None { cleanup } => cleanup. hash_stable ( hcx, hasher) ,
174+ }
175+ }
176+ }
177+
171178// State of a local variable
172179#[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
173180pub enum LocalValue {
@@ -195,9 +202,14 @@ impl<'tcx> LocalValue {
195202 }
196203}
197204
205+ impl_stable_hash_for ! ( enum self :: LocalValue {
206+ Dead ,
207+ Live ( x) ,
208+ } ) ;
209+
198210/// The virtual machine state during const-evaluation at a given point in time.
199- #[ derive( Eq , PartialEq , Hash ) ]
200- pub ( crate ) struct EvalSnapshot < ' a , ' mir , ' tcx : ' a + ' mir , M : Machine < ' mir , ' tcx > > {
211+ #[ derive( Eq , PartialEq ) ]
212+ struct EvalSnapshot < ' a , ' mir , ' tcx : ' a + ' mir , M : Machine < ' mir , ' tcx > > {
201213 machine : M ,
202214 memory : Memory < ' a , ' mir , ' tcx , M > ,
203215 stack : Vec < Frame < ' mir , ' tcx > > ,
@@ -215,6 +227,27 @@ impl<'a, 'mir, 'tcx, M> EvalSnapshot<'a, 'mir, 'tcx, M>
215227 }
216228}
217229
230+ impl < ' a , ' mir , ' tcx , M > Hash for EvalSnapshot < ' a , ' mir , ' tcx , M >
231+ where M : Machine < ' mir , ' tcx > ,
232+ {
233+ fn hash < H : Hasher > ( & self , state : & mut H ) {
234+ // Implement in terms of hash stable, so that k1 == k2 -> hash(k1) == hash(k2)
235+ let mut hcx = self . memory . tcx . get_stable_hashing_context ( ) ;
236+ let mut hasher = StableHasher :: < u64 > :: new ( ) ;
237+ self . hash_stable ( & mut hcx, & mut hasher) ;
238+ hasher. finish ( ) . hash ( state)
239+ }
240+ }
241+
242+ impl < ' a , ' b , ' mir , ' tcx , M > HashStable < StableHashingContext < ' b > > for EvalSnapshot < ' a , ' mir , ' tcx , M >
243+ where M : Machine < ' mir , ' tcx > ,
244+ {
245+ fn hash_stable < W : StableHasherResult > ( & self , hcx : & mut StableHashingContext < ' b > , hasher : & mut StableHasher < W > ) {
246+ let EvalSnapshot { machine, memory, stack } = self ;
247+ ( machine, & memory. data , stack) . hash_stable ( hcx, hasher) ;
248+ }
249+ }
250+
218251pub ( super ) struct InfiniteLoopDetector < ' a , ' mir , ' tcx : ' a + ' mir , M : Machine < ' mir , ' tcx > > {
219252 /// The set of all `EvalSnapshot` *hashes* observed by this detector.
220253 ///
@@ -258,9 +291,10 @@ impl<'a, 'mir, 'tcx, M> InfiniteLoopDetector<'a, 'mir, 'tcx, M>
258291 stack : & [ Frame < ' mir , ' tcx > ] ,
259292 ) -> EvalResult < ' tcx , ( ) > {
260293
261- let mut fx = FxHasher :: default ( ) ;
262- ( machine, memory, stack) . hash ( & mut fx) ;
263- let hash = fx. finish ( ) ;
294+ let mut hcx = memory. tcx . get_stable_hashing_context ( ) ;
295+ let mut hasher = StableHasher :: < u64 > :: new ( ) ;
296+ ( machine, stack) . hash_stable ( & mut hcx, & mut hasher) ;
297+ let hash = hasher. finish ( ) ;
264298
265299 if self . hashes . insert ( hash) {
266300 // No collision
0 commit comments