Make TraitEngine::new use the right solver, add compare mode
This commit is contained in:
parent
b637048a89
commit
3d4da98273
8 changed files with 49 additions and 32 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()),
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>) {
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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",
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue