@@ -204,7 +204,10 @@ struct TraitObligationStack<'prev, 'tcx> {
204
204
#[ derive( Clone , Default ) ]
205
205
pub struct SelectionCache < ' tcx > {
206
206
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
+ > ,
208
211
> ,
209
212
}
210
213
@@ -490,7 +493,9 @@ impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
490
493
491
494
#[ derive( Clone , Default ) ]
492
495
pub 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
+ > ,
494
499
}
495
500
496
501
impl < ' cx , ' tcx > SelectionContext < ' cx , ' tcx > {
@@ -1143,15 +1148,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1143
1148
let tcx = self . tcx ( ) ;
1144
1149
if self . can_use_global_caches ( param_env) {
1145
1150
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) ) {
1147
1152
return Some ( cached. get ( tcx) ) ;
1148
1153
}
1149
1154
}
1150
1155
self . infcx
1151
1156
. evaluation_cache
1152
1157
. hashmap
1153
1158
. borrow ( )
1154
- . get ( & trait_ref)
1159
+ . get ( & param_env . and ( trait_ref) )
1155
1160
. map ( |v| v. get ( tcx) )
1156
1161
}
1157
1162
@@ -1182,7 +1187,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1182
1187
. evaluation_cache
1183
1188
. hashmap
1184
1189
. borrow_mut ( )
1185
- . insert ( trait_ref, WithDepNode :: new ( dep_node, result) ) ;
1190
+ . insert ( param_env . and ( trait_ref) , WithDepNode :: new ( dep_node, result) ) ;
1186
1191
return ;
1187
1192
}
1188
1193
}
@@ -1195,7 +1200,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1195
1200
. evaluation_cache
1196
1201
. hashmap
1197
1202
. borrow_mut ( )
1198
- . insert ( trait_ref, WithDepNode :: new ( dep_node, result) ) ;
1203
+ . insert ( param_env . and ( trait_ref) , WithDepNode :: new ( dep_node, result) ) ;
1199
1204
}
1200
1205
1201
1206
/// For various reasons, it's possible for a subobligation
@@ -1567,14 +1572,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1567
1572
/// Do note that if the type itself is not in the
1568
1573
/// global tcx, the local caches will be used.
1569
1574
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 ( ) {
1578
1579
return false ;
1579
1580
}
1580
1581
@@ -1602,15 +1603,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1602
1603
let trait_ref = & cache_fresh_trait_pred. skip_binder ( ) . trait_ref ;
1603
1604
if self . can_use_global_caches ( param_env) {
1604
1605
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) ) {
1606
1607
return Some ( cached. get ( tcx) ) ;
1607
1608
}
1608
1609
}
1609
1610
self . infcx
1610
1611
. selection_cache
1611
1612
. hashmap
1612
1613
. borrow ( )
1613
- . get ( trait_ref)
1614
+ . get ( & param_env . and ( * trait_ref) )
1614
1615
. map ( |v| v. get ( tcx) )
1615
1616
}
1616
1617
@@ -1671,7 +1672,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1671
1672
tcx. selection_cache
1672
1673
. hashmap
1673
1674
. borrow_mut ( )
1674
- . insert ( trait_ref, WithDepNode :: new ( dep_node, candidate) ) ;
1675
+ . insert ( param_env . and ( trait_ref) , WithDepNode :: new ( dep_node, candidate) ) ;
1675
1676
return ;
1676
1677
}
1677
1678
}
@@ -1685,7 +1686,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1685
1686
. selection_cache
1686
1687
. hashmap
1687
1688
. borrow_mut ( )
1688
- . insert ( trait_ref, WithDepNode :: new ( dep_node, candidate) ) ;
1689
+ . insert ( param_env . and ( trait_ref) , WithDepNode :: new ( dep_node, candidate) ) ;
1689
1690
}
1690
1691
1691
1692
fn assemble_candidates < ' o > (
0 commit comments