Skip to content

Commit 80f109a

Browse files
compiler-errorscuviper
authored andcommitted
Only disable cache if predicate has opaques within it
(cherry picked from commit 4915373)
1 parent 5f7387c commit 80f109a

File tree

1 file changed

+45
-21
lines changed
  • compiler/rustc_trait_selection/src/traits/select

1 file changed

+45
-21
lines changed

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

+45-21
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,26 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
1212
use rustc_data_structures::stack::ensure_sufficient_stack;
1313
use rustc_errors::{Diag, EmissionGuarantee};
1414
use rustc_hir as hir;
15-
use rustc_hir::LangItem;
1615
use rustc_hir::def_id::DefId;
17-
use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType};
18-
use rustc_infer::infer::DefineOpaqueTypes;
16+
use rustc_hir::LangItem;
1917
use rustc_infer::infer::at::ToTrace;
2018
use rustc_infer::infer::relate::TypeRelation;
19+
use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType};
20+
use rustc_infer::infer::DefineOpaqueTypes;
2121
use rustc_infer::traits::TraitObligation;
2222
use rustc_middle::bug;
23-
use rustc_middle::dep_graph::{DepNodeIndex, dep_kinds};
23+
use rustc_middle::dep_graph::{dep_kinds, DepNodeIndex};
2424
use rustc_middle::mir::interpret::ErrorHandled;
2525
pub use rustc_middle::traits::select::*;
2626
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
2727
use rustc_middle::ty::error::TypeErrorToStringExt;
28-
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
28+
use rustc_middle::ty::print::{with_no_trimmed_paths, PrintTraitRefExt as _};
2929
use rustc_middle::ty::{
3030
self, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitableExt,
3131
Upcast,
3232
};
33-
use rustc_span::Symbol;
3433
use rustc_span::symbol::sym;
34+
use rustc_span::Symbol;
3535
use tracing::{debug, instrument, trace};
3636

3737
use self::EvaluationResult::*;
@@ -40,9 +40,9 @@ use super::coherence::{self, Conflict};
4040
use super::project::ProjectionTermObligation;
4141
use super::util::closure_trait_ref_and_return_type;
4242
use super::{
43-
ImplDerivedCause, Normalized, Obligation, ObligationCause, ObligationCauseCode, Overflow,
44-
PolyTraitObligation, PredicateObligation, Selection, SelectionError, SelectionResult,
45-
TraitQueryMode, const_evaluatable, project, util, wf,
43+
const_evaluatable, project, util, wf, ImplDerivedCause, Normalized, Obligation,
44+
ObligationCause, ObligationCauseCode, Overflow, PolyTraitObligation, PredicateObligation,
45+
Selection, SelectionError, SelectionResult, TraitQueryMode,
4646
};
4747
use crate::error_reporting::InferCtxtErrorExt;
4848
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
@@ -1306,7 +1306,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13061306
}
13071307

13081308
let tcx = self.tcx();
1309-
if self.can_use_global_caches(param_env) {
1309+
if self.can_use_global_caches(param_env, trait_pred) {
13101310
if let Some(res) = tcx.evaluation_cache.get(&(param_env, trait_pred), tcx) {
13111311
return Some(res);
13121312
}
@@ -1335,7 +1335,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13351335
return;
13361336
}
13371337

1338-
if self.can_use_global_caches(param_env) && !trait_pred.has_infer() {
1338+
if self.can_use_global_caches(param_env, trait_pred) && !trait_pred.has_infer() {
13391339
debug!(?trait_pred, ?result, "insert_evaluation_cache global");
13401340
// This may overwrite the cache with the same value
13411341
// FIXME: Due to #50507 this overwrites the different values
@@ -1479,7 +1479,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14791479
}
14801480

14811481
/// Returns `true` if the global caches can be used.
1482-
fn can_use_global_caches(&self, param_env: ty::ParamEnv<'tcx>) -> bool {
1482+
fn can_use_global_caches(
1483+
&self,
1484+
param_env: ty::ParamEnv<'tcx>,
1485+
pred: ty::PolyTraitPredicate<'tcx>,
1486+
) -> bool {
14831487
// If there are any inference variables in the `ParamEnv`, then we
14841488
// always use a cache local to this particular scope. Otherwise, we
14851489
// switch to a global cache.
@@ -1500,7 +1504,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15001504

15011505
// Avoid using the global cache when we're defining opaque types
15021506
// as their hidden type may impact the result of candidate selection.
1503-
if !self.infcx.defining_opaque_types().is_empty() {
1507+
//
1508+
// HACK: This is still theoretically unsound. Goals can indirectly rely
1509+
// on opaques in the defining scope, and it's easier to do so with TAIT.
1510+
// However, if we disqualify *all* goals from being cached, perf suffers.
1511+
// This is likely fixed by better caching in general in the new solver.
1512+
// See: <https://github.com/rust-lang/rust/issues/132064>.
1513+
if !self.infcx.defining_opaque_types().is_empty() && pred.has_opaque_types() {
15041514
return false;
15051515
}
15061516

@@ -1523,7 +1533,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15231533
let tcx = self.tcx();
15241534
let pred = cache_fresh_trait_pred.skip_binder();
15251535

1526-
if self.can_use_global_caches(param_env) {
1536+
if self.can_use_global_caches(param_env, cache_fresh_trait_pred) {
15271537
if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
15281538
return Some(res);
15291539
}
@@ -1580,7 +1590,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15801590
return;
15811591
}
15821592

1583-
if self.can_use_global_caches(param_env) {
1593+
if self.can_use_global_caches(param_env, cache_fresh_trait_pred) {
15841594
if let Err(Overflow(OverflowError::Canonical)) = candidate {
15851595
// Don't cache overflow globally; we only produce this in certain modes.
15861596
} else if !pred.has_infer() && !candidate.has_infer() {
@@ -1787,7 +1797,11 @@ enum DropVictim {
17871797

17881798
impl DropVictim {
17891799
fn drop_if(should_drop: bool) -> DropVictim {
1790-
if should_drop { DropVictim::Yes } else { DropVictim::No }
1800+
if should_drop {
1801+
DropVictim::Yes
1802+
} else {
1803+
DropVictim::No
1804+
}
17911805
}
17921806
}
17931807

@@ -1891,7 +1905,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18911905
(ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(victim_cand)) => {
18921906
// Prefer these to a global where-clause bound
18931907
// (see issue #50825).
1894-
if is_global(*victim_cand) { DropVictim::Yes } else { DropVictim::No }
1908+
if is_global(*victim_cand) {
1909+
DropVictim::Yes
1910+
} else {
1911+
DropVictim::No
1912+
}
18951913
}
18961914
(
18971915
ImplCandidate(_)
@@ -2450,9 +2468,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
24502468
} else {
24512469
// If this is an ill-formed auto/built-in trait, then synthesize
24522470
// new error args for the missing generics.
2453-
let err_args = ty::GenericArgs::extend_with_error(tcx, trait_def_id, &[
2454-
normalized_ty.into(),
2455-
]);
2471+
let err_args = ty::GenericArgs::extend_with_error(
2472+
tcx,
2473+
trait_def_id,
2474+
&[normalized_ty.into()],
2475+
);
24562476
ty::TraitRef::new_from_args(tcx, trait_def_id, err_args)
24572477
};
24582478

@@ -3154,7 +3174,11 @@ impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> {
31543174
}
31553175

31563176
fn depth(&self) -> usize {
3157-
if let Some(head) = self.head { head.depth } else { 0 }
3177+
if let Some(head) = self.head {
3178+
head.depth
3179+
} else {
3180+
0
3181+
}
31583182
}
31593183
}
31603184

0 commit comments

Comments
 (0)