Skip to content

Commit 85c8fd9

Browse files
committed
Make EvaluationCache consider polarity as cache's key
1 parent da8873e commit 85c8fd9

File tree

2 files changed

+28
-8
lines changed
  • compiler
    • rustc_middle/src/traits
    • rustc_trait_selection/src/traits/select

2 files changed

+28
-8
lines changed

compiler/rustc_middle/src/traits/select.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ pub type SelectionCache<'tcx> = Cache<
1616
SelectionResult<'tcx, SelectionCandidate<'tcx>>,
1717
>;
1818

19-
pub type EvaluationCache<'tcx> =
20-
Cache<ty::ParamEnvAnd<'tcx, ty::ConstnessAnd<ty::PolyTraitRef<'tcx>>>, EvaluationResult>;
19+
pub type EvaluationCache<'tcx> = Cache<
20+
(ty::ParamEnvAnd<'tcx, ty::ConstnessAnd<ty::PolyTraitRef<'tcx>>>, ty::ImplPolarity),
21+
EvaluationResult,
22+
>;
2123

2224
/// The selection process begins by considering all impls, where
2325
/// clauses, and so forth that might resolve an obligation. Sometimes

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

+24-6
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
709709

710710
debug!(?fresh_trait_ref);
711711

712-
if let Some(result) = self.check_evaluation_cache(obligation.param_env, fresh_trait_ref) {
712+
if let Some(result) = self.check_evaluation_cache(
713+
obligation.param_env,
714+
fresh_trait_ref,
715+
obligation.predicate.skip_binder().polarity,
716+
) {
713717
debug!(?result, "CACHE HIT");
714718
return Ok(result);
715719
}
@@ -739,12 +743,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
739743
let reached_depth = stack.reached_depth.get();
740744
if reached_depth >= stack.depth {
741745
debug!(?result, "CACHE MISS");
742-
self.insert_evaluation_cache(obligation.param_env, fresh_trait_ref, dep_node, result);
746+
self.insert_evaluation_cache(
747+
obligation.param_env,
748+
fresh_trait_ref,
749+
obligation.predicate.skip_binder().polarity,
750+
dep_node,
751+
result,
752+
);
743753

744754
stack.cache().on_completion(stack.dfn, |fresh_trait_ref, provisional_result| {
745755
self.insert_evaluation_cache(
746756
obligation.param_env,
747757
fresh_trait_ref,
758+
obligation.predicate.skip_binder().polarity,
748759
dep_node,
749760
provisional_result.max(result),
750761
);
@@ -977,6 +988,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
977988
&self,
978989
param_env: ty::ParamEnv<'tcx>,
979990
trait_ref: ty::ConstnessAnd<ty::PolyTraitRef<'tcx>>,
991+
polarity: ty::ImplPolarity,
980992
) -> Option<EvaluationResult> {
981993
// Neither the global nor local cache is aware of intercrate
982994
// mode, so don't do any caching. In particular, we might
@@ -988,17 +1000,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
9881000

9891001
let tcx = self.tcx();
9901002
if self.can_use_global_caches(param_env) {
991-
if let Some(res) = tcx.evaluation_cache.get(&param_env.and(trait_ref), tcx) {
1003+
if let Some(res) = tcx.evaluation_cache.get(&(param_env.and(trait_ref), polarity), tcx)
1004+
{
9921005
return Some(res);
9931006
}
9941007
}
995-
self.infcx.evaluation_cache.get(&param_env.and(trait_ref), tcx)
1008+
self.infcx.evaluation_cache.get(&(param_env.and(trait_ref), polarity), tcx)
9961009
}
9971010

9981011
fn insert_evaluation_cache(
9991012
&mut self,
10001013
param_env: ty::ParamEnv<'tcx>,
10011014
trait_ref: ty::ConstnessAnd<ty::PolyTraitRef<'tcx>>,
1015+
polarity: ty::ImplPolarity,
10021016
dep_node: DepNodeIndex,
10031017
result: EvaluationResult,
10041018
) {
@@ -1023,13 +1037,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10231037
// FIXME: Due to #50507 this overwrites the different values
10241038
// This should be changed to use HashMapExt::insert_same
10251039
// when that is fixed
1026-
self.tcx().evaluation_cache.insert(param_env.and(trait_ref), dep_node, result);
1040+
self.tcx().evaluation_cache.insert(
1041+
(param_env.and(trait_ref), polarity),
1042+
dep_node,
1043+
result,
1044+
);
10271045
return;
10281046
}
10291047
}
10301048

10311049
debug!(?trait_ref, ?result, "insert_evaluation_cache");
1032-
self.infcx.evaluation_cache.insert(param_env.and(trait_ref), dep_node, result);
1050+
self.infcx.evaluation_cache.insert((param_env.and(trait_ref), polarity), dep_node, result);
10331051
}
10341052

10351053
/// For various reasons, it's possible for a subobligation

0 commit comments

Comments
 (0)