Skip to content

Commit 4915373

Browse files
Only disable cache if predicate has opaques within it
1 parent 82c24ec commit 4915373

File tree

1 file changed

+18
-6
lines changed
  • compiler/rustc_trait_selection/src/traits/select

1 file changed

+18
-6
lines changed

Diff for: compiler/rustc_trait_selection/src/traits/select/mod.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13101310
trait_pred: ty::PolyTraitPredicate<'tcx>,
13111311
) -> Option<EvaluationResult> {
13121312
let tcx = self.tcx();
1313-
if self.can_use_global_caches(param_env) {
1313+
if self.can_use_global_caches(param_env, trait_pred) {
13141314
if let Some(res) = tcx.evaluation_cache.get(&(param_env, trait_pred), tcx) {
13151315
return Some(res);
13161316
}
@@ -1331,7 +1331,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13311331
return;
13321332
}
13331333

1334-
if self.can_use_global_caches(param_env) && !trait_pred.has_infer() {
1334+
if self.can_use_global_caches(param_env, trait_pred) && !trait_pred.has_infer() {
13351335
debug!(?trait_pred, ?result, "insert_evaluation_cache global");
13361336
// This may overwrite the cache with the same value
13371337
// FIXME: Due to #50507 this overwrites the different values
@@ -1476,7 +1476,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14761476
}
14771477

14781478
/// Returns `true` if the global caches can be used.
1479-
fn can_use_global_caches(&self, param_env: ty::ParamEnv<'tcx>) -> bool {
1479+
fn can_use_global_caches(
1480+
&self,
1481+
param_env: ty::ParamEnv<'tcx>,
1482+
pred: ty::PolyTraitPredicate<'tcx>,
1483+
) -> bool {
14801484
// If there are any inference variables in the `ParamEnv`, then we
14811485
// always use a cache local to this particular scope. Otherwise, we
14821486
// switch to a global cache.
@@ -1494,7 +1498,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14941498
TypingMode::Coherence => false,
14951499
// Avoid using the global cache when we're defining opaque types
14961500
// as their hidden type may impact the result of candidate selection.
1497-
TypingMode::Analysis { defining_opaque_types } => defining_opaque_types.is_empty(),
1501+
//
1502+
// HACK: This is still theoretically unsound. Goals can indirectly rely
1503+
// on opaques in the defining scope, and it's easier to do so with TAIT.
1504+
// However, if we disqualify *all* goals from being cached, perf suffers.
1505+
// This is likely fixed by better caching in general in the new solver.
1506+
// See: <https://github.com/rust-lang/rust/issues/132064>.
1507+
TypingMode::Analysis { defining_opaque_types } => {
1508+
defining_opaque_types.is_empty() || !pred.has_opaque_types()
1509+
}
14981510
// The global cache is only used if there are no opaque types in
14991511
// the defining scope or we're outside of analysis.
15001512
//
@@ -1512,7 +1524,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15121524
let tcx = self.tcx();
15131525
let pred = cache_fresh_trait_pred.skip_binder();
15141526

1515-
if self.can_use_global_caches(param_env) {
1527+
if self.can_use_global_caches(param_env, cache_fresh_trait_pred) {
15161528
if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
15171529
return Some(res);
15181530
}
@@ -1562,7 +1574,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15621574
return;
15631575
}
15641576

1565-
if self.can_use_global_caches(param_env) {
1577+
if self.can_use_global_caches(param_env, cache_fresh_trait_pred) {
15661578
if let Err(Overflow(OverflowError::Canonical)) = candidate {
15671579
// Don't cache overflow globally; we only produce this in certain modes.
15681580
} else if !pred.has_infer() && !candidate.has_infer() {

0 commit comments

Comments
 (0)