Skip to content

Commit 6a51d66

Browse files
committed
traits/select: pass the whole cache key to can_use_global_caches.
1 parent 9ee7a15 commit 6a51d66

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
@@ -1286,13 +1293,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12861293
span: rustc_span::Span,
12871294
) {
12881295
let tcx = self.tcx();
1289-
let trait_ref = cache_fresh_trait_pred.skip_binder().trait_ref;
12901296

12911297
if !self.can_cache_candidate(&candidate) {
12921298
debug!(
1293-
"insert_candidate_cache(trait_ref={:?}, candidate={:?} -\
1299+
"insert_candidate_cache(predicate={:?}, candidate={:?} -\
12941300
candidate is not cacheable",
1295-
trait_ref, candidate
1301+
cache_fresh_trait_pred, candidate
12961302
);
12971303
return;
12981304
}
@@ -1302,33 +1308,32 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13021308
return;
13031309
}
13041310

1305-
let cache = if self.can_use_global_caches(param_env) && !trait_ref.has_local_value() {
1311+
// FIXME(eddyb) reuse the key between checking the cache and inserting.
1312+
let cache_key = param_env.and(cache_fresh_trait_pred);
1313+
let cache = if self.can_use_global_caches(&cache_key) {
13061314
if candidate.has_local_value() {
13071315
span_bug!(
13081316
span,
1309-
"selecting inference-free `{}` resulted in `{:?}`?!",
1310-
trait_ref,
1317+
"selecting inference-free `{:?}` resulted in `{:?}`?!",
1318+
cache_fresh_trait_pred,
13111319
candidate,
13121320
);
13131321
}
13141322
debug!(
1315-
"insert_candidate_cache(trait_ref={:?}, candidate={:?}) global",
1316-
trait_ref, candidate,
1323+
"insert_candidate_cache(predicate={:?}, candidate={:?}) global",
1324+
cache_fresh_trait_pred, candidate,
13171325
);
13181326
// This may overwrite the cache with the same value.
13191327
&tcx.selection_cache
13201328
} else {
13211329
debug!(
1322-
"insert_candidate_cache(trait_ref={:?}, candidate={:?}) local",
1323-
trait_ref, candidate,
1330+
"insert_candidate_cache(predicate={:?}, candidate={:?}) local",
1331+
cache_fresh_trait_pred, candidate,
13241332
);
13251333
&self.infcx.selection_cache
13261334
};
13271335

1328-
cache
1329-
.hashmap
1330-
.borrow_mut()
1331-
.insert(param_env.and(trait_ref), WithDepNode::new(dep_node, candidate));
1336+
cache.hashmap.borrow_mut().insert(cache_key, WithDepNode::new(dep_node, candidate));
13321337
}
13331338

13341339
fn assemble_candidates<'o>(

0 commit comments

Comments
 (0)