Skip to content

Commit 3b6593a

Browse files
authored
Rollup merge of #107103 - compiler-errors:new-solver-evaluate_obligation, r=lcnr
Use new solver in `evaluate_obligation` query (when new solver is enabled) (only when `-Ztrait-solver=next`, of course) ... Does this make sense? It seems to me like it should be reasonable, but maybe there's some reason why this is a bad idea. r? ``@lcnr`` Needs a perf run because I guess this `solver == TraitSolver::Next` check is on a hot path.
2 parents 28188d1 + 5bfd90e commit 3b6593a

File tree

1 file changed

+37
-6
lines changed

1 file changed

+37
-6
lines changed

compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs

+37-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use rustc_middle::ty;
2+
use rustc_session::config::TraitSolver;
23

34
use crate::infer::canonical::OriginalQueryValues;
45
use crate::infer::InferCtxt;
6+
use crate::solve::{Certainty, Goal, InferCtxtEvalExt, MaybeCause};
57
use crate::traits::{EvaluationResult, OverflowError, PredicateObligation, SelectionContext};
68

79
pub trait InferCtxtExt<'tcx> {
@@ -77,12 +79,38 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
7779
_ => obligation.param_env.without_const(),
7880
};
7981

80-
let c_pred = self
81-
.canonicalize_query_keep_static(param_env.and(obligation.predicate), &mut _orig_values);
82-
// Run canonical query. If overflow occurs, rerun from scratch but this time
83-
// in standard trait query mode so that overflow is handled appropriately
84-
// within `SelectionContext`.
85-
self.tcx.at(obligation.cause.span()).evaluate_obligation(c_pred)
82+
if self.tcx.sess.opts.unstable_opts.trait_solver != TraitSolver::Next {
83+
let c_pred = self.canonicalize_query_keep_static(
84+
param_env.and(obligation.predicate),
85+
&mut _orig_values,
86+
);
87+
self.tcx.at(obligation.cause.span()).evaluate_obligation(c_pred)
88+
} else {
89+
self.probe(|snapshot| {
90+
if let Ok((_, certainty)) =
91+
self.evaluate_root_goal(Goal::new(self.tcx, param_env, obligation.predicate))
92+
{
93+
match certainty {
94+
Certainty::Yes => {
95+
if self.opaque_types_added_in_snapshot(snapshot) {
96+
Ok(EvaluationResult::EvaluatedToOkModuloOpaqueTypes)
97+
} else if self.region_constraints_added_in_snapshot(snapshot).is_some()
98+
{
99+
Ok(EvaluationResult::EvaluatedToOkModuloRegions)
100+
} else {
101+
Ok(EvaluationResult::EvaluatedToOk)
102+
}
103+
}
104+
Certainty::Maybe(MaybeCause::Ambiguity) => {
105+
Ok(EvaluationResult::EvaluatedToAmbig)
106+
}
107+
Certainty::Maybe(MaybeCause::Overflow) => Err(OverflowError::Canonical),
108+
}
109+
} else {
110+
Ok(EvaluationResult::EvaluatedToErr)
111+
}
112+
})
113+
}
86114
}
87115

88116
// Helper function that canonicalizes and runs the query. If an
@@ -92,6 +120,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
92120
&self,
93121
obligation: &PredicateObligation<'tcx>,
94122
) -> EvaluationResult {
123+
// Run canonical query. If overflow occurs, rerun from scratch but this time
124+
// in standard trait query mode so that overflow is handled appropriately
125+
// within `SelectionContext`.
95126
match self.evaluate_obligation(obligation) {
96127
Ok(result) => result,
97128
Err(OverflowError::Canonical) => {

0 commit comments

Comments
 (0)