@@ -141,7 +141,7 @@ pub struct CtxtInterners<'tcx> {
141141 canonical_var_infos : InternedSet < ' tcx , List < CanonicalVarInfo < ' tcx > > > ,
142142 region : InternedSet < ' tcx , RegionKind < ' tcx > > ,
143143 poly_existential_predicates : InternedSet < ' tcx , List < PolyExistentialPredicate < ' tcx > > > ,
144- predicate : InternedSet < ' tcx , PredicateS < ' tcx > > ,
144+ predicate : InternedSet < ' tcx , WithStableHash < PredicateS < ' tcx > > > ,
145145 predicates : InternedSet < ' tcx , List < Predicate < ' tcx > > > ,
146146 projs : InternedSet < ' tcx , List < ProjectionKind > > ,
147147 place_elems : InternedSet < ' tcx , List < PlaceElem < ' tcx > > > ,
@@ -188,20 +188,8 @@ impl<'tcx> CtxtInterners<'tcx> {
188188 self . type_
189189 . intern ( kind, |kind| {
190190 let flags = super :: flags:: FlagComputation :: for_kind ( & kind) ;
191-
192- // It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them.
193- // Without incremental, we rarely stable-hash types, so let's not do it proactively.
194- let stable_hash = if flags. flags . intersects ( TypeFlags :: NEEDS_INFER )
195- || sess. opts . incremental . is_none ( )
196- {
197- Fingerprint :: ZERO
198- } else {
199- let mut hasher = StableHasher :: new ( ) ;
200- let mut hcx =
201- StableHashingContext :: new ( sess, definitions, cstore, source_span) ;
202- kind. hash_stable ( & mut hcx, & mut hasher) ;
203- hasher. finish ( )
204- } ;
191+ let stable_hash =
192+ self . stable_hash ( & flags, sess, definitions, cstore, source_span, & kind) ;
205193
206194 let ty_struct = TyS {
207195 kind,
@@ -217,20 +205,54 @@ impl<'tcx> CtxtInterners<'tcx> {
217205 ) )
218206 }
219207
208+ fn stable_hash < ' a , T : HashStable < StableHashingContext < ' a > > > (
209+ & self ,
210+ flags : & ty:: flags:: FlagComputation ,
211+ sess : & ' a Session ,
212+ definitions : & ' a rustc_hir:: definitions:: Definitions ,
213+ cstore : & ' a CrateStoreDyn ,
214+ source_span : & ' a IndexVec < LocalDefId , Span > ,
215+ val : & T ,
216+ ) -> Fingerprint {
217+ // It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them.
218+ // Without incremental, we rarely stable-hash types, so let's not do it proactively.
219+ if flags. flags . intersects ( TypeFlags :: NEEDS_INFER ) || sess. opts . incremental . is_none ( ) {
220+ Fingerprint :: ZERO
221+ } else {
222+ let mut hasher = StableHasher :: new ( ) ;
223+ let mut hcx = StableHashingContext :: new ( sess, definitions, cstore, source_span) ;
224+ val. hash_stable ( & mut hcx, & mut hasher) ;
225+ hasher. finish ( )
226+ }
227+ }
228+
220229 #[ inline( never) ]
221- fn intern_predicate ( & self , kind : Binder < ' tcx , PredicateKind < ' tcx > > ) -> Predicate < ' tcx > {
230+ fn intern_predicate (
231+ & self ,
232+ kind : Binder < ' tcx , PredicateKind < ' tcx > > ,
233+ sess : & Session ,
234+ definitions : & rustc_hir:: definitions:: Definitions ,
235+ cstore : & CrateStoreDyn ,
236+ source_span : & IndexVec < LocalDefId , Span > ,
237+ ) -> Predicate < ' tcx > {
222238 Predicate ( Interned :: new_unchecked (
223239 self . predicate
224240 . intern ( kind, |kind| {
225241 let flags = super :: flags:: FlagComputation :: for_predicate ( kind) ;
226242
243+ let stable_hash =
244+ self . stable_hash ( & flags, sess, definitions, cstore, source_span, & kind) ;
245+
227246 let predicate_struct = PredicateS {
228247 kind,
229248 flags : flags. flags ,
230249 outer_exclusive_binder : flags. outer_exclusive_binder ,
231250 } ;
232251
233- InternedInSet ( self . arena . alloc ( predicate_struct) )
252+ InternedInSet (
253+ self . arena
254+ . alloc ( WithStableHash { internee : predicate_struct, stable_hash } ) ,
255+ )
234256 } )
235257 . 0 ,
236258 ) )
@@ -2158,23 +2180,25 @@ impl<'tcx> Hash for InternedInSet<'tcx, WithStableHash<TyS<'tcx>>> {
21582180 }
21592181}
21602182
2161- impl < ' tcx > Borrow < Binder < ' tcx , PredicateKind < ' tcx > > > for InternedInSet < ' tcx , PredicateS < ' tcx > > {
2183+ impl < ' tcx > Borrow < Binder < ' tcx , PredicateKind < ' tcx > > >
2184+ for InternedInSet < ' tcx , WithStableHash < PredicateS < ' tcx > > >
2185+ {
21622186 fn borrow < ' a > ( & ' a self ) -> & ' a Binder < ' tcx , PredicateKind < ' tcx > > {
21632187 & self . 0 . kind
21642188 }
21652189}
21662190
2167- impl < ' tcx > PartialEq for InternedInSet < ' tcx , PredicateS < ' tcx > > {
2168- fn eq ( & self , other : & InternedInSet < ' tcx , PredicateS < ' tcx > > ) -> bool {
2191+ impl < ' tcx > PartialEq for InternedInSet < ' tcx , WithStableHash < PredicateS < ' tcx > > > {
2192+ fn eq ( & self , other : & InternedInSet < ' tcx , WithStableHash < PredicateS < ' tcx > > > ) -> bool {
21692193 // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
21702194 // `x == y`.
21712195 self . 0 . kind == other. 0 . kind
21722196 }
21732197}
21742198
2175- impl < ' tcx > Eq for InternedInSet < ' tcx , PredicateS < ' tcx > > { }
2199+ impl < ' tcx > Eq for InternedInSet < ' tcx , WithStableHash < PredicateS < ' tcx > > > { }
21762200
2177- impl < ' tcx > Hash for InternedInSet < ' tcx , PredicateS < ' tcx > > {
2201+ impl < ' tcx > Hash for InternedInSet < ' tcx , WithStableHash < PredicateS < ' tcx > > > {
21782202 fn hash < H : Hasher > ( & self , s : & mut H ) {
21792203 // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
21802204 self . 0 . kind . hash ( s)
@@ -2373,7 +2397,14 @@ impl<'tcx> TyCtxt<'tcx> {
23732397
23742398 #[ inline]
23752399 pub fn mk_predicate ( self , binder : Binder < ' tcx , PredicateKind < ' tcx > > ) -> Predicate < ' tcx > {
2376- self . interners . intern_predicate ( binder)
2400+ self . interners . intern_predicate (
2401+ binder,
2402+ self . sess ,
2403+ & self . definitions . read ( ) ,
2404+ & * self . untracked_resolutions . cstore ,
2405+ // This is only used to create a stable hashing context.
2406+ & self . untracked_resolutions . source_span ,
2407+ )
23772408 }
23782409
23792410 #[ inline]
0 commit comments