Rollup merge of #107279 - compiler-errors:new-solver-evaluate, r=lcnr
Use new solver during selection r? ``@lcnr``
This commit is contained in:
commit
5683915ca4
@ -38,6 +38,8 @@ use rustc_errors::Diagnostic;
|
|||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||||
|
use rustc_infer::traits::TraitEngine;
|
||||||
|
use rustc_infer::traits::TraitEngineExt;
|
||||||
use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
|
use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||||
@ -47,6 +49,7 @@ use rustc_middle::ty::relate::TypeRelation;
|
|||||||
use rustc_middle::ty::SubstsRef;
|
use rustc_middle::ty::SubstsRef;
|
||||||
use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
|
use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
|
||||||
use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitable};
|
use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitable};
|
||||||
|
use rustc_session::config::TraitSolver;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
@ -544,10 +547,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
) -> Result<EvaluationResult, OverflowError> {
|
) -> Result<EvaluationResult, OverflowError> {
|
||||||
self.evaluation_probe(|this| {
|
self.evaluation_probe(|this| {
|
||||||
this.evaluate_predicate_recursively(
|
if this.tcx().sess.opts.unstable_opts.trait_solver != TraitSolver::Next {
|
||||||
TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
|
this.evaluate_predicate_recursively(
|
||||||
obligation.clone(),
|
TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
|
||||||
)
|
obligation.clone(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
this.evaluate_predicates_recursively_in_new_solver([obligation.clone()])
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,18 +593,40 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
where
|
where
|
||||||
I: IntoIterator<Item = PredicateObligation<'tcx>> + std::fmt::Debug,
|
I: IntoIterator<Item = PredicateObligation<'tcx>> + std::fmt::Debug,
|
||||||
{
|
{
|
||||||
let mut result = EvaluatedToOk;
|
if self.tcx().sess.opts.unstable_opts.trait_solver != TraitSolver::Next {
|
||||||
for obligation in predicates {
|
let mut result = EvaluatedToOk;
|
||||||
let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?;
|
for obligation in predicates {
|
||||||
if let EvaluatedToErr = eval {
|
let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?;
|
||||||
// fast-path - EvaluatedToErr is the top of the lattice,
|
if let EvaluatedToErr = eval {
|
||||||
// so we don't need to look on the other predicates.
|
// fast-path - EvaluatedToErr is the top of the lattice,
|
||||||
return Ok(EvaluatedToErr);
|
// so we don't need to look on the other predicates.
|
||||||
} else {
|
return Ok(EvaluatedToErr);
|
||||||
result = cmp::max(result, eval);
|
} else {
|
||||||
|
result = cmp::max(result, eval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Ok(result)
|
||||||
|
} else {
|
||||||
|
self.evaluate_predicates_recursively_in_new_solver(predicates)
|
||||||
}
|
}
|
||||||
Ok(result)
|
}
|
||||||
|
|
||||||
|
/// Evaluates the predicates using the new solver when `-Ztrait-solver=next` is enabled
|
||||||
|
fn evaluate_predicates_recursively_in_new_solver(
|
||||||
|
&mut self,
|
||||||
|
predicates: impl IntoIterator<Item = PredicateObligation<'tcx>>,
|
||||||
|
) -> Result<EvaluationResult, OverflowError> {
|
||||||
|
let mut fulfill_cx = crate::solve::FulfillmentCtxt::new();
|
||||||
|
fulfill_cx.register_predicate_obligations(self.infcx, predicates);
|
||||||
|
// True errors
|
||||||
|
if !fulfill_cx.select_where_possible(self.infcx).is_empty() {
|
||||||
|
return Ok(EvaluatedToErr);
|
||||||
|
}
|
||||||
|
if !fulfill_cx.select_all_or_error(self.infcx).is_empty() {
|
||||||
|
return Ok(EvaluatedToAmbig);
|
||||||
|
}
|
||||||
|
// Regions and opaques are handled in the `evaluation_probe` by looking at the snapshot
|
||||||
|
Ok(EvaluatedToOk)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(
|
#[instrument(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user