Make TraitEngine::new use the right solver, add compare mode

This commit is contained in:
Michael Goulet 2023-05-31 01:21:38 +00:00
parent b637048a89
commit 3d4da98273
8 changed files with 49 additions and 32 deletions

View file

@ -161,8 +161,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
&self, &self,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Option<(Ty<'tcx>, Vec<traits::PredicateObligation<'tcx>>)> { ) -> Option<(Ty<'tcx>, Vec<traits::PredicateObligation<'tcx>>)> {
let tcx = self.infcx.tcx; let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new_in_snapshot(self.infcx);
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new_in_snapshot(tcx);
let cause = traits::ObligationCause::misc(self.span, self.body_id); let cause = traits::ObligationCause::misc(self.span, self.body_id);
let normalized_ty = match self let normalized_ty = match self

View file

@ -1549,7 +1549,7 @@ pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
.with_opaque_type_inference(DefiningAnchor::Bind(def_id)) .with_opaque_type_inference(DefiningAnchor::Bind(def_id))
.build(); .build();
let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(infcx.tcx); let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx);
for (predicate, cause) in generator_interior_predicates { for (predicate, cause) in generator_interior_predicates {
let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate); let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate);
fulfillment_cx.register_predicate_obligation(&infcx, obligation); fulfillment_cx.register_predicate_obligation(&infcx, obligation);

View file

@ -86,8 +86,8 @@ impl<'tcx> Inherited<'tcx> {
Inherited { Inherited {
typeck_results, typeck_results,
fulfillment_cx: RefCell::new(<dyn TraitEngine<'_>>::new(&infcx)),
infcx, infcx,
fulfillment_cx: RefCell::new(<dyn TraitEngine<'_>>::new(tcx)),
locals: RefCell::new(Default::default()), locals: RefCell::new(Default::default()),
deferred_sized_obligations: RefCell::new(Vec::new()), deferred_sized_obligations: RefCell::new(Vec::new()),
deferred_call_resolutions: RefCell::new(Default::default()), deferred_call_resolutions: RefCell::new(Default::default()),

View file

@ -231,17 +231,15 @@ impl<'tcx> InferCtxt<'tcx> {
{ {
let (a, b) = if relation.a_is_expected() { (a, b) } else { (b, a) }; let (a, b) = if relation.a_is_expected() { (a, b) } else { (b, a) };
relation.register_predicates([ty::Binder::dummy( relation.register_predicates([ty::Binder::dummy(if self.next_trait_solver() {
if self.next_trait_solver() { ty::PredicateKind::AliasRelate(
ty::PredicateKind::AliasRelate( a.into(),
a.into(), b.into(),
b.into(), ty::AliasRelationDirection::Equate,
ty::AliasRelationDirection::Equate, )
) } else {
} else { ty::PredicateKind::ConstEquate(a, b)
ty::PredicateKind::ConstEquate(a, b) })]);
},
)]);
return Ok(b); return Ok(b);
} }

View file

@ -27,26 +27,42 @@ use rustc_session::config::TraitSolver;
use rustc_span::Span; use rustc_span::Span;
pub trait TraitEngineExt<'tcx> { pub trait TraitEngineExt<'tcx> {
fn new(tcx: TyCtxt<'tcx>) -> Box<Self>; fn new(infcx: &InferCtxt<'tcx>) -> Box<Self>;
fn new_in_snapshot(tcx: TyCtxt<'tcx>) -> Box<Self>; fn new_in_snapshot(infcx: &InferCtxt<'tcx>) -> Box<Self>;
} }
impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> { impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
fn new(tcx: TyCtxt<'tcx>) -> Box<Self> { fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> {
match tcx.sess.opts.unstable_opts.trait_solver { match (infcx.tcx.sess.opts.unstable_opts.trait_solver, infcx.next_trait_solver()) {
TraitSolver::Classic => Box::new(FulfillmentContext::new()), (TraitSolver::Classic, false) | (TraitSolver::NextCoherence, false) => {
TraitSolver::NextCoherence => Box::new(FulfillmentContext::new()), Box::new(FulfillmentContext::new())
TraitSolver::Chalk => Box::new(ChalkFulfillmentContext::new()), }
TraitSolver::Next => Box::new(NextFulfillmentCtxt::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> { fn new_in_snapshot(infcx: &InferCtxt<'tcx>) -> Box<Self> {
match tcx.sess.opts.unstable_opts.trait_solver { match (infcx.tcx.sess.opts.unstable_opts.trait_solver, infcx.next_trait_solver()) {
TraitSolver::Classic => Box::new(FulfillmentContext::new_in_snapshot()), (TraitSolver::Classic, false) | (TraitSolver::NextCoherence, false) => {
TraitSolver::NextCoherence => Box::new(FulfillmentContext::new_in_snapshot()), Box::new(FulfillmentContext::new_in_snapshot())
TraitSolver::Chalk => Box::new(ChalkFulfillmentContext::new_in_snapshot()), }
TraitSolver::Next => Box::new(NextFulfillmentCtxt::new()), (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()
),
} }
} }
} }
@ -60,11 +76,11 @@ pub struct ObligationCtxt<'a, 'tcx> {
impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self { 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 { 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>) { pub fn register_obligation(&self, obligation: PredicateObligation<'tcx>) {

View file

@ -55,7 +55,7 @@ pub fn codegen_select_candidate<'tcx>(
// Currently, we use a fulfillment context to completely resolve // Currently, we use a fulfillment context to completely resolve
// all nested obligations. This is because they can inform the // all nested obligations. This is because they can inform the
// inference of the impl's type parameters. // inference of the impl's type parameters.
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(tcx); let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(&infcx);
let impl_source = selection.map(|predicate| { let impl_source = selection.map(|predicate| {
fulfill_cx.register_predicate_obligation(&infcx, predicate); fulfill_cx.register_predicate_obligation(&infcx, predicate);
}); });

View file

@ -108,6 +108,7 @@ string_enum! {
Polonius => "polonius", Polonius => "polonius",
Chalk => "chalk", Chalk => "chalk",
NextSolver => "next-solver", NextSolver => "next-solver",
NextSolverCoherence => "next-solver-coherence",
SplitDwarf => "split-dwarf", SplitDwarf => "split-dwarf",
SplitDwarfSingle => "split-dwarf-single", SplitDwarfSingle => "split-dwarf-single",
} }

View file

@ -2127,6 +2127,9 @@ impl<'test> TestCx<'test> {
Some(CompareMode::NextSolver) => { Some(CompareMode::NextSolver) => {
rustc.args(&["-Ztrait-solver=next"]); rustc.args(&["-Ztrait-solver=next"]);
} }
Some(CompareMode::NextSolverCoherence) => {
rustc.args(&["-Ztrait-solver=next-coherence"]);
}
Some(CompareMode::SplitDwarf) if self.config.target.contains("windows") => { Some(CompareMode::SplitDwarf) if self.config.target.contains("windows") => {
rustc.args(&["-Csplit-debuginfo=unpacked", "-Zunstable-options"]); rustc.args(&["-Csplit-debuginfo=unpacked", "-Zunstable-options"]);
} }