Rollup merge of #112122 - compiler-errors:next-coherence, r=lcnr
Add `-Ztrait-solver=next-coherence` Flag that conditionally uses the trait solver *only* during coherence, for more testing and/or eventual partial-migration onto the trait solver (in the medium- to long-term). * This still uses the selection context in some of the coherence methods I think, so it's not "complete". Putting this up for review and/or for further work in-tree. * I probably need to spend a bit more time making sure that we don't sneakily create any other infcx's during coherence that also need the new solver enabled. r? `@lcnr`
This commit is contained in:
commit
0b002eb906
35 changed files with 142 additions and 63 deletions
|
@ -187,6 +187,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||
let (ref infcx, input, var_values) = tcx
|
||||
.infer_ctxt()
|
||||
.intercrate(intercrate)
|
||||
.with_next_trait_solver(true)
|
||||
.with_opaque_type_inference(canonical_input.value.anchor)
|
||||
.build_with_canonical(DUMMY_SP, &canonical_input);
|
||||
|
||||
|
|
|
@ -182,6 +182,7 @@ fn overlap<'tcx>(
|
|||
.with_opaque_type_inference(DefiningAnchor::Bubble)
|
||||
.skip_leak_check(skip_leak_check.is_yes())
|
||||
.intercrate(true)
|
||||
.with_next_trait_solver(tcx.next_trait_solver_in_coherence())
|
||||
.build();
|
||||
let selcx = &mut SelectionContext::new(&infcx);
|
||||
if track_ambiguity_causes.is_yes() {
|
||||
|
|
|
@ -27,24 +27,42 @@ use rustc_session::config::TraitSolver;
|
|||
use rustc_span::Span;
|
||||
|
||||
pub trait TraitEngineExt<'tcx> {
|
||||
fn new(tcx: TyCtxt<'tcx>) -> Box<Self>;
|
||||
fn new_in_snapshot(tcx: TyCtxt<'tcx>) -> Box<Self>;
|
||||
fn new(infcx: &InferCtxt<'tcx>) -> Box<Self>;
|
||||
fn new_in_snapshot(infcx: &InferCtxt<'tcx>) -> Box<Self>;
|
||||
}
|
||||
|
||||
impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
|
||||
fn new(tcx: TyCtxt<'tcx>) -> Box<Self> {
|
||||
match tcx.sess.opts.unstable_opts.trait_solver {
|
||||
TraitSolver::Classic => Box::new(FulfillmentContext::new()),
|
||||
TraitSolver::Chalk => Box::new(ChalkFulfillmentContext::new()),
|
||||
TraitSolver::Next => Box::new(NextFulfillmentCtxt::new()),
|
||||
fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> {
|
||||
match (infcx.tcx.sess.opts.unstable_opts.trait_solver, infcx.next_trait_solver()) {
|
||||
(TraitSolver::Classic, false) | (TraitSolver::NextCoherence, false) => {
|
||||
Box::new(FulfillmentContext::new())
|
||||
}
|
||||
(TraitSolver::Next | TraitSolver::NextCoherence, true) => {
|
||||
Box::new(NextFulfillmentCtxt::new())
|
||||
}
|
||||
(TraitSolver::Chalk, false) => Box::new(ChalkFulfillmentContext::new()),
|
||||
_ => bug!(
|
||||
"incompatible combination of -Ztrait-solver flag ({:?}) and InferCtxt::next_trait_solver ({:?})",
|
||||
infcx.tcx.sess.opts.unstable_opts.trait_solver,
|
||||
infcx.next_trait_solver()
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_in_snapshot(tcx: TyCtxt<'tcx>) -> Box<Self> {
|
||||
match tcx.sess.opts.unstable_opts.trait_solver {
|
||||
TraitSolver::Classic => Box::new(FulfillmentContext::new_in_snapshot()),
|
||||
TraitSolver::Chalk => Box::new(ChalkFulfillmentContext::new_in_snapshot()),
|
||||
TraitSolver::Next => Box::new(NextFulfillmentCtxt::new()),
|
||||
fn new_in_snapshot(infcx: &InferCtxt<'tcx>) -> Box<Self> {
|
||||
match (infcx.tcx.sess.opts.unstable_opts.trait_solver, infcx.next_trait_solver()) {
|
||||
(TraitSolver::Classic, false) | (TraitSolver::NextCoherence, false) => {
|
||||
Box::new(FulfillmentContext::new_in_snapshot())
|
||||
}
|
||||
(TraitSolver::Next | TraitSolver::NextCoherence, true) => {
|
||||
Box::new(NextFulfillmentCtxt::new())
|
||||
}
|
||||
(TraitSolver::Chalk, false) => Box::new(ChalkFulfillmentContext::new_in_snapshot()),
|
||||
_ => bug!(
|
||||
"incompatible combination of -Ztrait-solver flag ({:?}) and InferCtxt::next_trait_solver ({:?})",
|
||||
infcx.tcx.sess.opts.unstable_opts.trait_solver,
|
||||
infcx.next_trait_solver()
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,11 +76,11 @@ pub struct ObligationCtxt<'a, 'tcx> {
|
|||
|
||||
impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
|
||||
pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
|
||||
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'_>>::new(infcx.tcx)) }
|
||||
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'_>>::new(infcx)) }
|
||||
}
|
||||
|
||||
pub fn new_in_snapshot(infcx: &'a InferCtxt<'tcx>) -> Self {
|
||||
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'_>>::new_in_snapshot(infcx.tcx)) }
|
||||
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'_>>::new_in_snapshot(infcx)) }
|
||||
}
|
||||
|
||||
pub fn register_obligation(&self, obligation: PredicateObligation<'tcx>) {
|
||||
|
|
|
@ -1047,7 +1047,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
// (which may fail).
|
||||
span_bug!(span, "WF predicate not satisfied for {:?}", ty);
|
||||
}
|
||||
TraitSolver::Chalk | TraitSolver::Next => {
|
||||
TraitSolver::Chalk | TraitSolver::Next | TraitSolver::NextCoherence => {
|
||||
// FIXME: we'll need a better message which takes into account
|
||||
// which bounds actually failed to hold.
|
||||
self.tcx.sess.struct_span_err(
|
||||
|
|
|
@ -78,7 +78,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
_ => obligation.param_env.without_const(),
|
||||
};
|
||||
|
||||
if self.tcx.trait_solver_next() {
|
||||
if self.next_trait_solver() {
|
||||
self.probe(|snapshot| {
|
||||
let mut fulfill_cx = crate::solve::FulfillmentCtxt::new();
|
||||
fulfill_cx.register_predicate_obligation(self, obligation.clone());
|
||||
|
|
|
@ -146,7 +146,7 @@ where
|
|||
infcx: &InferCtxt<'tcx>,
|
||||
span: Span,
|
||||
) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
|
||||
if infcx.tcx.trait_solver_next() {
|
||||
if infcx.next_trait_solver() {
|
||||
return Ok(scrape_region_constraints(
|
||||
infcx,
|
||||
|ocx| QueryTypeOp::perform_locally_in_new_solver(ocx, self),
|
||||
|
|
|
@ -539,7 +539,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
self.evaluation_probe(|this| {
|
||||
let goal =
|
||||
this.infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env));
|
||||
let mut result = if this.tcx().trait_solver_next() {
|
||||
let mut result = if this.infcx.next_trait_solver() {
|
||||
this.evaluate_predicates_recursively_in_new_solver([obligation.clone()])?
|
||||
} else {
|
||||
this.evaluate_predicate_recursively(
|
||||
|
@ -593,7 +593,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
where
|
||||
I: IntoIterator<Item = PredicateObligation<'tcx>> + std::fmt::Debug,
|
||||
{
|
||||
if self.tcx().trait_solver_next() {
|
||||
if self.infcx.next_trait_solver() {
|
||||
self.evaluate_predicates_recursively_in_new_solver(predicates)
|
||||
} else {
|
||||
let mut result = EvaluatedToOk;
|
||||
|
|
|
@ -21,7 +21,7 @@ impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> {
|
|||
) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>> {
|
||||
assert!(!ty.is_ty_var(), "should have resolved vars before calling");
|
||||
|
||||
if self.infcx.tcx.trait_solver_next() {
|
||||
if self.infcx.next_trait_solver() {
|
||||
while let ty::Alias(ty::Projection, projection_ty) = *ty.kind() {
|
||||
let new_infer_ty = self.infcx.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::NormalizeProjectionType,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue