@@ -835,13 +835,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
835835 trait_ref : ty:: PolyTraitRef < ' tcx > ,
836836 ) -> Option < EvaluationResult > {
837837 let tcx = self . tcx ( ) ;
838- let cache = if self . can_use_global_caches ( param_env) && !trait_ref. has_local_value ( ) {
838+ // FIXME(eddyb) pass in the `ty::PolyTraitPredicate` instead.
839+ let predicate = trait_ref. map_bound ( |trait_ref| ty:: TraitPredicate { trait_ref } ) ;
840+ // FIXME(eddyb) reuse the key between checking the cache and inserting.
841+ let cache_key = param_env. and ( predicate) ;
842+ let cache = if self . can_use_global_caches ( & cache_key) {
839843 & tcx. evaluation_cache
840844 } else {
841845 & self . infcx . evaluation_cache
842846 } ;
843847
844- cache. hashmap . borrow ( ) . get ( & param_env . and ( trait_ref ) ) . map ( |v| v. get ( tcx) )
848+ cache. hashmap . borrow ( ) . get ( & cache_key ) . map ( |v| v. get ( tcx) )
845849 }
846850
847851 fn insert_evaluation_cache (
@@ -857,7 +861,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
857861 return ;
858862 }
859863
860- let cache = if self . can_use_global_caches ( param_env) && !trait_ref. has_local_value ( ) {
864+ // FIXME(eddyb) pass in the `ty::PolyTraitPredicate` instead.
865+ let predicate = trait_ref. map_bound ( |trait_ref| ty:: TraitPredicate { trait_ref } ) ;
866+ // FIXME(eddyb) reuse the key between checking the cache and inserting.
867+ let cache_key = param_env. and ( predicate) ;
868+ let cache = if self . can_use_global_caches ( & cache_key) {
861869 debug ! (
862870 "insert_evaluation_cache(trait_ref={:?}, candidate={:?}) global" ,
863871 trait_ref, result,
@@ -872,10 +880,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
872880 & self . infcx . evaluation_cache
873881 } ;
874882
875- cache
876- . hashmap
877- . borrow_mut ( )
878- . insert ( param_env. and ( trait_ref) , WithDepNode :: new ( dep_node, result) ) ;
883+ cache. hashmap . borrow_mut ( ) . insert ( cache_key, WithDepNode :: new ( dep_node, result) ) ;
879884 }
880885
881886 /// For various reasons, it's possible for a subobligation
@@ -950,7 +955,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
950955 debug_assert ! ( !stack. obligation. predicate. has_escaping_bound_vars( ) ) ;
951956
952957 if let Some ( c) =
953- self . check_candidate_cache ( stack. obligation . param_env , & cache_fresh_trait_pred)
958+ self . check_candidate_cache ( stack. obligation . param_env , cache_fresh_trait_pred)
954959 {
955960 debug ! ( "CACHE HIT: SELECT({:?})={:?}" , cache_fresh_trait_pred, c) ;
956961 return c;
@@ -1208,13 +1213,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12081213 }
12091214
12101215 /// Returns `true` if the global caches can be used.
1211- /// Do note that if the type itself is not in the
1212- /// global tcx, the local caches will be used.
1213- fn can_use_global_caches ( & self , param_env : ty:: ParamEnv < ' tcx > ) -> bool {
1214- // If there are any e.g. inference variables in the `ParamEnv`, then we
1215- // always use a cache local to this particular scope. Otherwise, we
1216- // switch to a global cache.
1217- if param_env. has_local_value ( ) {
1216+ fn can_use_global_caches (
1217+ & self ,
1218+ cache_key : & ty:: ParamEnvAnd < ' tcx , ty:: PolyTraitPredicate < ' tcx > > ,
1219+ ) -> bool {
1220+ // If there are any e.g. inference variables in the `ParamEnv` or predicate,
1221+ // then we always use a cache local to this particular inference context.
1222+ // Otherwise, we switch to a global cache.
1223+ if cache_key. has_local_value ( ) {
12181224 return false ;
12191225 }
12201226
@@ -1236,17 +1242,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12361242 fn check_candidate_cache (
12371243 & mut self ,
12381244 param_env : ty:: ParamEnv < ' tcx > ,
1239- cache_fresh_trait_pred : & ty:: PolyTraitPredicate < ' tcx > ,
1245+ cache_fresh_trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
12401246 ) -> Option < SelectionResult < ' tcx , SelectionCandidate < ' tcx > > > {
12411247 let tcx = self . tcx ( ) ;
1242- let trait_ref = & cache_fresh_trait_pred. skip_binder ( ) . trait_ref ;
1243- let cache = if self . can_use_global_caches ( param_env) && !trait_ref. has_local_value ( ) {
1248+ // FIXME(eddyb) reuse the key between checking the cache and inserting.
1249+ let cache_key = param_env. and ( cache_fresh_trait_pred) ;
1250+ let cache = if self . can_use_global_caches ( & cache_key) {
12441251 & tcx. selection_cache
12451252 } else {
12461253 & self . infcx . selection_cache
12471254 } ;
12481255
1249- cache. hashmap . borrow ( ) . get ( & param_env . and ( * trait_ref ) ) . map ( |v| v. get ( tcx) )
1256+ cache. hashmap . borrow ( ) . get ( & cache_key ) . map ( |v| v. get ( tcx) )
12501257 }
12511258
12521259 /// Determines whether can we safely cache the result
@@ -1284,13 +1291,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12841291 span : rustc_span:: Span ,
12851292 ) {
12861293 let tcx = self . tcx ( ) ;
1287- let trait_ref = cache_fresh_trait_pred. skip_binder ( ) . trait_ref ;
12881294
12891295 if !self . can_cache_candidate ( & candidate) {
12901296 debug ! (
1291- "insert_candidate_cache(trait_ref ={:?}, candidate={:?} -\
1297+ "insert_candidate_cache(predicate ={:?}, candidate={:?} -\
12921298 candidate is not cacheable",
1293- trait_ref , candidate
1299+ cache_fresh_trait_pred , candidate
12941300 ) ;
12951301 return ;
12961302 }
@@ -1300,33 +1306,32 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13001306 return ;
13011307 }
13021308
1303- let cache = if self . can_use_global_caches ( param_env) && !trait_ref. has_local_value ( ) {
1309+ // FIXME(eddyb) reuse the key between checking the cache and inserting.
1310+ let cache_key = param_env. and ( cache_fresh_trait_pred) ;
1311+ let cache = if self . can_use_global_caches ( & cache_key) {
13041312 if candidate. has_local_value ( ) {
13051313 span_bug ! (
13061314 span,
1307- "selecting inference-free `{}` resulted in `{:?}`?!" ,
1308- trait_ref ,
1315+ "selecting inference-free `{:? }` resulted in `{:?}`?!" ,
1316+ cache_fresh_trait_pred ,
13091317 candidate,
13101318 ) ;
13111319 }
13121320 debug ! (
1313- "insert_candidate_cache(trait_ref ={:?}, candidate={:?}) global" ,
1314- trait_ref , candidate,
1321+ "insert_candidate_cache(predicate ={:?}, candidate={:?}) global" ,
1322+ cache_fresh_trait_pred , candidate,
13151323 ) ;
13161324 // This may overwrite the cache with the same value.
13171325 & tcx. selection_cache
13181326 } else {
13191327 debug ! (
1320- "insert_candidate_cache(trait_ref ={:?}, candidate={:?}) local" ,
1321- trait_ref , candidate,
1328+ "insert_candidate_cache(predicate ={:?}, candidate={:?}) local" ,
1329+ cache_fresh_trait_pred , candidate,
13221330 ) ;
13231331 & self . infcx . selection_cache
13241332 } ;
13251333
1326- cache
1327- . hashmap
1328- . borrow_mut ( )
1329- . insert ( param_env. and ( trait_ref) , WithDepNode :: new ( dep_node, candidate) ) ;
1334+ cache. hashmap . borrow_mut ( ) . insert ( cache_key, WithDepNode :: new ( dep_node, candidate) ) ;
13301335 }
13311336
13321337 fn assemble_candidates < ' o > (
0 commit comments