Skip to content

Commit 2bc133c

Browse files
committed
traits/select: pass the whole cache key to can_use_global_caches.
1 parent 8b9e4ba commit 2bc133c

File tree

2 files changed

+43
-35
lines changed

2 files changed

+43
-35
lines changed

src/librustc/traits/select.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_hir::def_id::DefId;
1717
pub struct SelectionCache<'tcx> {
1818
pub hashmap: Lock<
1919
FxHashMap<
20-
ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>,
20+
ty::ParamEnvAnd<'tcx, ty::PolyTraitPredicate<'tcx>>,
2121
WithDepNode<SelectionResult<'tcx, SelectionCandidate<'tcx>>>,
2222
>,
2323
>,
@@ -261,7 +261,10 @@ impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
261261
#[derive(Clone, Default)]
262262
pub struct EvaluationCache<'tcx> {
263263
pub hashmap: Lock<
264-
FxHashMap<ty::ParamEnvAnd<'tcx, ty::PolyTraitRef<'tcx>>, WithDepNode<EvaluationResult>>,
264+
FxHashMap<
265+
ty::ParamEnvAnd<'tcx, ty::PolyTraitPredicate<'tcx>>,
266+
WithDepNode<EvaluationResult>,
267+
>,
265268
>,
266269
}
267270

src/librustc_infer/traits/select.rs

+38-33
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)