Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not use ParamEnv::and when building a cache key from a param-env and trait eval candidate #95031

Merged
merged 1 commit into from
Apr 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions compiler/rustc_middle/src/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@ use rustc_hir::def_id::DefId;
use rustc_query_system::cache::Cache;

pub type SelectionCache<'tcx> = Cache<
ty::ParamEnvAnd<'tcx, ty::TraitPredicate<'tcx>>,
// This cache does not use `ParamEnvAnd` in its keys because `ParamEnv::and` can replace
// caller bounds with an empty list if the `TraitPredicate` looks global, which may happen
// after erasing lifetimes from the predicate.
(ty::ParamEnv<'tcx>, ty::TraitPredicate<'tcx>),
compiler-errors marked this conversation as resolved.
Show resolved Hide resolved
SelectionResult<'tcx, SelectionCandidate<'tcx>>,
>;

pub type EvaluationCache<'tcx> =
Cache<ty::ParamEnvAnd<'tcx, ty::PolyTraitPredicate<'tcx>>, EvaluationResult>;
pub type EvaluationCache<'tcx> = Cache<
// See above: this cache does not use `ParamEnvAnd` in its keys due to sometimes incorrectly
// caching with the wrong `ParamEnv`.
(ty::ParamEnv<'tcx>, ty::PolyTraitPredicate<'tcx>),
EvaluationResult,
>;

/// The selection process begins by considering all impls, where
/// clauses, and so forth that might resolve an obligation. Sometimes
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1046,11 +1046,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {

let tcx = self.tcx();
if self.can_use_global_caches(param_env) {
if let Some(res) = tcx.evaluation_cache.get(&param_env.and(trait_pred), tcx) {
if let Some(res) = tcx.evaluation_cache.get(&(param_env, trait_pred), tcx) {
return Some(res);
}
}
self.infcx.evaluation_cache.get(&param_env.and(trait_pred), tcx)
self.infcx.evaluation_cache.get(&(param_env, trait_pred), tcx)
}

fn insert_evaluation_cache(
Expand Down Expand Up @@ -1081,13 +1081,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// FIXME: Due to #50507 this overwrites the different values
// This should be changed to use HashMapExt::insert_same
// when that is fixed
self.tcx().evaluation_cache.insert(param_env.and(trait_pred), dep_node, result);
self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result);
return;
}
}

debug!(?trait_pred, ?result, "insert_evaluation_cache");
self.infcx.evaluation_cache.insert(param_env.and(trait_pred), dep_node, result);
self.infcx.evaluation_cache.insert((param_env, trait_pred), dep_node, result);
}

/// For various reasons, it's possible for a subobligation
Expand Down Expand Up @@ -1297,11 +1297,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pred.remap_constness(tcx, &mut param_env);

if self.can_use_global_caches(param_env) {
if let Some(res) = tcx.selection_cache.get(&param_env.and(pred), tcx) {
if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
return Some(res);
}
}
self.infcx.selection_cache.get(&param_env.and(pred), tcx)
self.infcx.selection_cache.get(&(param_env, pred), tcx)
}

/// Determines whether can we safely cache the result
Expand Down Expand Up @@ -1361,14 +1361,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if !candidate.needs_infer() {
debug!(?pred, ?candidate, "insert_candidate_cache global");
// This may overwrite the cache with the same value.
tcx.selection_cache.insert(param_env.and(pred), dep_node, candidate);
tcx.selection_cache.insert((param_env, pred), dep_node, candidate);
return;
}
}
}

debug!(?pred, ?candidate, "insert_candidate_cache local");
self.infcx.selection_cache.insert(param_env.and(pred), dep_node, candidate);
self.infcx.selection_cache.insert((param_env, pred), dep_node, candidate);
}

/// Matches a predicate against the bounds of its self type.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// check-pass
// build-pass
// edition:2018

type BoxFuture<T> = std::pin::Pin<Box<dyn std::future::Future<Output=T>>>;
Expand Down Expand Up @@ -65,6 +65,7 @@ async fn run<S>(dep: &str)
where
S: Storage,
for<'a> SaveUser<'a>: StorageRequest<S>,
for<'a> SaveUser<'a>: StorageRequestReturnType,
{
User { dep }.save().await;
}