create a "provisional cache" to restore performance in the case of cycles Introduce a "provisional cache" that caches the results of auto trait resolutions but keeps them from entering the *main* cache until everything is ready. This turned out a bit more complex than I hoped, but I don't see another short term fix -- happy to take suggestions! In the meantime, it's very clear we need to rework the trait solver. This resolves the extreme performance slowdown experienced in #60846 -- I plan to add a perf.rust-lang.org regression test to track this. Caveat: I've not run `x.py test` in full yet. r? @pnkfelix cc @arielb1 Fixes #60846
36 lines
1.0 KiB
Rust
36 lines
1.0 KiB
Rust
use rustc::traits::query::CanonicalPredicateGoal;
|
|
use rustc::traits::{
|
|
EvaluationResult, Obligation, ObligationCause, OverflowError, SelectionContext, TraitQueryMode,
|
|
};
|
|
use rustc::ty::query::Providers;
|
|
use rustc::ty::{ParamEnvAnd, TyCtxt};
|
|
use syntax::source_map::DUMMY_SP;
|
|
|
|
crate fn provide(p: &mut Providers<'_>) {
|
|
*p = Providers {
|
|
evaluate_obligation,
|
|
..*p
|
|
};
|
|
}
|
|
|
|
fn evaluate_obligation<'tcx>(
|
|
tcx: TyCtxt<'tcx>,
|
|
canonical_goal: CanonicalPredicateGoal<'tcx>,
|
|
) -> Result<EvaluationResult, OverflowError> {
|
|
tcx.infer_ctxt().enter_with_canonical(
|
|
DUMMY_SP,
|
|
&canonical_goal,
|
|
|ref infcx, goal, _canonical_inference_vars| {
|
|
let ParamEnvAnd {
|
|
param_env,
|
|
value: predicate,
|
|
} = goal;
|
|
|
|
let mut selcx = SelectionContext::with_query_mode(&infcx, TraitQueryMode::Canonical);
|
|
let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);
|
|
|
|
selcx.evaluate_root_obligation(&obligation)
|
|
},
|
|
)
|
|
}
|