]> git.lizzy.rs Git - rust.git/commitdiff
Disable the evaluation cache when in intercrate mode
authorAaron Hill <aa1ronham@gmail.com>
Wed, 15 Sep 2021 23:17:38 +0000 (18:17 -0500)
committerAaron Hill <aa1ronham@gmail.com>
Wed, 15 Sep 2021 23:17:38 +0000 (18:17 -0500)
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.

compiler/rustc_trait_selection/src/traits/select/mod.rs

index 8adf9015933c3f6121a2e1cd9ea726b16163c548..27acb87d221b99e5e945bae434813f0e64b0c924 100644 (file)
@@ -982,6 +982,14 @@ fn check_evaluation_cache(
         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 @@ fn insert_evaluation_cache(
             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");