@@ -204,7 +204,10 @@ struct TraitObligationStack<'prev, 'tcx> {
204204#[ derive( Clone , Default ) ]
205205pub struct SelectionCache < ' tcx > {
206206 hashmap : Lock <
207- FxHashMap < ty:: TraitRef < ' tcx > , WithDepNode < SelectionResult < ' tcx , SelectionCandidate < ' tcx > > > > ,
207+ FxHashMap <
208+ ty:: ParamEnvAnd < ' tcx , ty:: TraitRef < ' tcx > > ,
209+ WithDepNode < SelectionResult < ' tcx , SelectionCandidate < ' tcx > > > ,
210+ > ,
208211 > ,
209212}
210213
@@ -490,7 +493,9 @@ impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
490493
491494#[ derive( Clone , Default ) ]
492495pub struct EvaluationCache < ' tcx > {
493- hashmap : Lock < FxHashMap < ty:: PolyTraitRef < ' tcx > , WithDepNode < EvaluationResult > > > ,
496+ hashmap : Lock <
497+ FxHashMap < ty:: ParamEnvAnd < ' tcx , ty:: PolyTraitRef < ' tcx > > , WithDepNode < EvaluationResult > > ,
498+ > ,
494499}
495500
496501impl < ' cx , ' tcx > SelectionContext < ' cx , ' tcx > {
@@ -1143,15 +1148,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11431148 let tcx = self . tcx ( ) ;
11441149 if self . can_use_global_caches ( param_env) {
11451150 let cache = tcx. evaluation_cache . hashmap . borrow ( ) ;
1146- if let Some ( cached) = cache. get ( & trait_ref) {
1151+ if let Some ( cached) = cache. get ( & param_env . and ( trait_ref) ) {
11471152 return Some ( cached. get ( tcx) ) ;
11481153 }
11491154 }
11501155 self . infcx
11511156 . evaluation_cache
11521157 . hashmap
11531158 . borrow ( )
1154- . get ( & trait_ref)
1159+ . get ( & param_env . and ( trait_ref) )
11551160 . map ( |v| v. get ( tcx) )
11561161 }
11571162
@@ -1182,7 +1187,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11821187 . evaluation_cache
11831188 . hashmap
11841189 . borrow_mut ( )
1185- . insert ( trait_ref, WithDepNode :: new ( dep_node, result) ) ;
1190+ . insert ( param_env . and ( trait_ref) , WithDepNode :: new ( dep_node, result) ) ;
11861191 return ;
11871192 }
11881193 }
@@ -1195,7 +1200,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11951200 . evaluation_cache
11961201 . hashmap
11971202 . borrow_mut ( )
1198- . insert ( trait_ref, WithDepNode :: new ( dep_node, result) ) ;
1203+ . insert ( param_env . and ( trait_ref) , WithDepNode :: new ( dep_node, result) ) ;
11991204 }
12001205
12011206 /// For various reasons, it's possible for a subobligation
@@ -1567,14 +1572,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15671572 /// Do note that if the type itself is not in the
15681573 /// global tcx, the local caches will be used.
15691574 fn can_use_global_caches ( & self , param_env : ty:: ParamEnv < ' tcx > ) -> bool {
1570- // If there are any where-clauses in scope, then we always use
1571- // a cache local to this particular scope. Otherwise, we
1572- // switch to a global cache. We used to try and draw
1573- // finer-grained distinctions, but that led to a serious of
1574- // annoying and weird bugs like #22019 and #18290. This simple
1575- // rule seems to be pretty clearly safe and also still retains
1576- // a very high hit rate (~95% when compiling rustc).
1577- if !param_env. caller_bounds . is_empty ( ) {
1575+ // If there are any e.g. inference variables in the `ParamEnv`, then we
1576+ // always use a cache local to this particular scope. Otherwise, we
1577+ // switch to a global cache.
1578+ if param_env. has_local_value ( ) {
15781579 return false ;
15791580 }
15801581
@@ -1602,15 +1603,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16021603 let trait_ref = & cache_fresh_trait_pred. skip_binder ( ) . trait_ref ;
16031604 if self . can_use_global_caches ( param_env) {
16041605 let cache = tcx. selection_cache . hashmap . borrow ( ) ;
1605- if let Some ( cached) = cache. get ( & trait_ref) {
1606+ if let Some ( cached) = cache. get ( & param_env . and ( * trait_ref) ) {
16061607 return Some ( cached. get ( tcx) ) ;
16071608 }
16081609 }
16091610 self . infcx
16101611 . selection_cache
16111612 . hashmap
16121613 . borrow ( )
1613- . get ( trait_ref)
1614+ . get ( & param_env . and ( * trait_ref) )
16141615 . map ( |v| v. get ( tcx) )
16151616 }
16161617
@@ -1671,7 +1672,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16711672 tcx. selection_cache
16721673 . hashmap
16731674 . borrow_mut ( )
1674- . insert ( trait_ref, WithDepNode :: new ( dep_node, candidate) ) ;
1675+ . insert ( param_env . and ( trait_ref) , WithDepNode :: new ( dep_node, candidate) ) ;
16751676 return ;
16761677 }
16771678 }
@@ -1685,7 +1686,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16851686 . selection_cache
16861687 . hashmap
16871688 . borrow_mut ( )
1688- . insert ( trait_ref, WithDepNode :: new ( dep_node, candidate) ) ;
1689+ . insert ( param_env . and ( trait_ref) , WithDepNode :: new ( dep_node, candidate) ) ;
16891690 }
16901691
16911692 fn assemble_candidates < ' o > (
0 commit comments