Skip to content

Commit

Permalink
Disable the evaluation cache when in intercrate mode
Browse files Browse the repository at this point in the history
It's possible to use the same `InferCtxt` with both
an intercrate and non-intercrate `SelectionContext`. However,
the local (inferctxt) evaluation cache is not aware of this
distinction, so this kind of `InferCtxt` re-use will pollute
the cache wth bad results.

This commit avoids the issue by disabling the evaluation cache
entirely during intercrate mode.
  • Loading branch information
Aaron1011 committed Sep 15, 2021
1 parent c3c0f80 commit 6d1f4d2
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Expand Up @@ -982,6 +982,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
param_env: ty::ParamEnv<'tcx>,
trait_ref: ty::ConstnessAnd<ty::PolyTraitRef<'tcx>>,
) -> Option<EvaluationResult> {
// Neither the global nor local cache is aware of intercrate
// mode, so don't do any caching. In particular, we might
// re-use the same `InferCtxt` with both an intercrate
// and non-intercrate `SelectionContext`
if self.intercrate {
return None;
}

let tcx = self.tcx();
if self.can_use_global_caches(param_env) {
if let Some(res) = tcx.evaluation_cache.get(&param_env.and(trait_ref), tcx) {
Expand All @@ -1004,6 +1012,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return;
}

// Neither the global nor local cache is aware of intercrate
// mode, so don't do any caching. In particular, we might
// re-use the same `InferCtxt` with both an intercrate
// and non-intercrate `SelectionContext`
if self.intercrate {
return;
}

if self.can_use_global_caches(param_env) {
if !trait_ref.needs_infer() {
debug!(?trait_ref, ?result, "insert_evaluation_cache global");
Expand Down

0 comments on commit 6d1f4d2

Please sign in to comment.