about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAaron Hill <aa1ronham@gmail.com>2021-09-15 18:17:38 -0500
committerAaron Hill <aa1ronham@gmail.com>2021-09-15 18:17:38 -0500
commit6d1f4d2fed2bdc561891d19440c38cf7adfb4858 (patch)
treee506ae5b14cc875dc9f8fa34709a9af0bc7836f2
parentc3c0f80d6081092faff801542dd82f0e2420152b (diff)
downloadrust-6d1f4d2fed2bdc561891d19440c38cf7adfb4858.tar.gz
rust-6d1f4d2fed2bdc561891d19440c38cf7adfb4858.zip
Disable the evaluation cache when in intercrate mode
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.
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs16
1 files changed, 16 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 8adf9015933..27acb87d221 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -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) {
@@ -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");