Canonicalize trait solver response inside probe
This commit is contained in:
parent
1f72129ffe
commit
b84b1da2db
4 changed files with 25 additions and 24 deletions
|
@ -1,7 +1,7 @@
|
||||||
//! Code shared by trait and projection goals for candidate assembly.
|
//! Code shared by trait and projection goals for candidate assembly.
|
||||||
|
|
||||||
use super::infcx_ext::InferCtxtExt;
|
use super::infcx_ext::InferCtxtExt;
|
||||||
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal};
|
use super::{CanonicalResponse, EvalCtxt, Goal, QueryResult};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_middle::ty::TypeFoldable;
|
use rustc_middle::ty::TypeFoldable;
|
||||||
|
@ -89,18 +89,18 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy {
|
||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
impl_def_id: DefId,
|
impl_def_id: DefId,
|
||||||
) -> Result<Certainty, NoSolution>;
|
) -> QueryResult<'tcx>;
|
||||||
|
|
||||||
fn consider_builtin_sized_candidate(
|
fn consider_builtin_sized_candidate(
|
||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
) -> Result<Certainty, NoSolution>;
|
) -> QueryResult<'tcx>;
|
||||||
|
|
||||||
fn consider_assumption(
|
fn consider_assumption(
|
||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
assumption: ty::Predicate<'tcx>,
|
assumption: ty::Predicate<'tcx>,
|
||||||
) -> Result<Certainty, NoSolution>;
|
) -> QueryResult<'tcx>;
|
||||||
}
|
}
|
||||||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<'tcx>>(
|
pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<'tcx>>(
|
||||||
|
@ -180,9 +180,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
tcx.for_each_relevant_impl(
|
tcx.for_each_relevant_impl(
|
||||||
goal.predicate.trait_def_id(tcx),
|
goal.predicate.trait_def_id(tcx),
|
||||||
goal.predicate.self_ty(),
|
goal.predicate.self_ty(),
|
||||||
|impl_def_id| match G::consider_impl_candidate(self, goal, impl_def_id)
|
|impl_def_id| match G::consider_impl_candidate(self, goal, impl_def_id) {
|
||||||
.and_then(|certainty| self.make_canonical_response(certainty))
|
|
||||||
{
|
|
||||||
Ok(result) => candidates
|
Ok(result) => candidates
|
||||||
.push(Candidate { source: CandidateSource::Impl(impl_def_id), result }),
|
.push(Candidate { source: CandidateSource::Impl(impl_def_id), result }),
|
||||||
Err(NoSolution) => (),
|
Err(NoSolution) => (),
|
||||||
|
@ -203,7 +201,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
Err(NoSolution)
|
Err(NoSolution)
|
||||||
};
|
};
|
||||||
|
|
||||||
match result.and_then(|certainty| self.make_canonical_response(certainty)) {
|
match result {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
|
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
|
||||||
}
|
}
|
||||||
|
@ -217,9 +215,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
candidates: &mut Vec<Candidate<'tcx>>,
|
candidates: &mut Vec<Candidate<'tcx>>,
|
||||||
) {
|
) {
|
||||||
for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
|
for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
|
||||||
match G::consider_assumption(self, goal, assumption)
|
match G::consider_assumption(self, goal, assumption) {
|
||||||
.and_then(|certainty| self.make_canonical_response(certainty))
|
|
||||||
{
|
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
|
candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
|
||||||
}
|
}
|
||||||
|
@ -268,9 +264,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
.subst_iter_copied(self.tcx(), alias_ty.substs)
|
.subst_iter_copied(self.tcx(), alias_ty.substs)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
match G::consider_assumption(self, goal, assumption)
|
match G::consider_assumption(self, goal, assumption) {
|
||||||
.and_then(|certainty| self.make_canonical_response(certainty))
|
|
||||||
{
|
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
candidates.push(Candidate { source: CandidateSource::AliasBound(i), result })
|
candidates.push(Candidate { source: CandidateSource::AliasBound(i), result })
|
||||||
}
|
}
|
||||||
|
|
|
@ -313,6 +313,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn evaluate_all_and_make_canonical_response(
|
||||||
|
&mut self,
|
||||||
|
goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
|
||||||
|
) -> QueryResult<'tcx> {
|
||||||
|
self.evaluate_all(goals).and_then(|certainty| self.make_canonical_response(certainty))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(infcx), ret)]
|
#[instrument(level = "debug", skip(infcx), ret)]
|
||||||
|
|
|
@ -191,7 +191,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
|
goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
|
||||||
impl_def_id: DefId,
|
impl_def_id: DefId,
|
||||||
) -> Result<Certainty, NoSolution> {
|
) -> QueryResult<'tcx> {
|
||||||
let tcx = ecx.tcx();
|
let tcx = ecx.tcx();
|
||||||
|
|
||||||
let goal_trait_ref = goal.predicate.projection_ty.trait_ref(tcx);
|
let goal_trait_ref = goal.predicate.projection_ty.trait_ref(tcx);
|
||||||
|
@ -229,7 +229,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||||
impl_def_id
|
impl_def_id
|
||||||
)? else {
|
)? else {
|
||||||
let certainty = Certainty::Maybe(MaybeCause::Ambiguity);
|
let certainty = Certainty::Maybe(MaybeCause::Ambiguity);
|
||||||
return Ok(trait_ref_certainty.unify_and(certainty));
|
return ecx.make_canonical_response(trait_ref_certainty.unify_and(certainty));
|
||||||
};
|
};
|
||||||
|
|
||||||
if !assoc_def.item.defaultness(tcx).has_value() {
|
if !assoc_def.item.defaultness(tcx).has_value() {
|
||||||
|
@ -286,14 +286,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||||
let rhs_certainty =
|
let rhs_certainty =
|
||||||
ecx.evaluate_all(nested_goals).expect("failed to unify with unconstrained term");
|
ecx.evaluate_all(nested_goals).expect("failed to unify with unconstrained term");
|
||||||
|
|
||||||
Ok(trait_ref_certainty.unify_and(rhs_certainty))
|
ecx.make_canonical_response(trait_ref_certainty.unify_and(rhs_certainty))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consider_builtin_sized_candidate(
|
fn consider_builtin_sized_candidate(
|
||||||
_ecx: &mut EvalCtxt<'_, 'tcx>,
|
_ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
) -> Result<Certainty, NoSolution> {
|
) -> QueryResult<'tcx> {
|
||||||
bug!("`Sized` does not have an associated type: {:?}", goal);
|
bug!("`Sized` does not have an associated type: {:?}", goal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||||
_ecx: &mut EvalCtxt<'_, 'tcx>,
|
_ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
_goal: Goal<'tcx, Self>,
|
_goal: Goal<'tcx, Self>,
|
||||||
assumption: ty::Predicate<'tcx>,
|
assumption: ty::Predicate<'tcx>,
|
||||||
) -> Result<Certainty, NoSolution> {
|
) -> QueryResult<'tcx> {
|
||||||
if let Some(_poly_projection_pred) = assumption.to_opt_poly_projection_pred() {
|
if let Some(_poly_projection_pred) = assumption.to_opt_poly_projection_pred() {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::iter;
|
||||||
|
|
||||||
use super::assembly::{self, Candidate, CandidateSource};
|
use super::assembly::{self, Candidate, CandidateSource};
|
||||||
use super::infcx_ext::InferCtxtExt;
|
use super::infcx_ext::InferCtxtExt;
|
||||||
use super::{Certainty, EvalCtxt, Goal, QueryResult};
|
use super::{EvalCtxt, Goal, QueryResult};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||||
|
@ -29,7 +29,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, TraitPredicate<'tcx>>,
|
goal: Goal<'tcx, TraitPredicate<'tcx>>,
|
||||||
impl_def_id: DefId,
|
impl_def_id: DefId,
|
||||||
) -> Result<Certainty, NoSolution> {
|
) -> QueryResult<'tcx> {
|
||||||
let tcx = ecx.tcx();
|
let tcx = ecx.tcx();
|
||||||
|
|
||||||
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
|
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||||
|
@ -53,14 +53,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|pred| goal.with(tcx, pred));
|
.map(|pred| goal.with(tcx, pred));
|
||||||
nested_goals.extend(where_clause_bounds);
|
nested_goals.extend(where_clause_bounds);
|
||||||
ecx.evaluate_all(nested_goals)
|
ecx.evaluate_all_and_make_canonical_response(nested_goals)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consider_builtin_sized_candidate(
|
fn consider_builtin_sized_candidate(
|
||||||
_ecx: &mut EvalCtxt<'_, 'tcx>,
|
_ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
_goal: Goal<'tcx, Self>,
|
_goal: Goal<'tcx, Self>,
|
||||||
) -> Result<Certainty, NoSolution> {
|
) -> QueryResult<'tcx> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||||
_ecx: &mut EvalCtxt<'_, 'tcx>,
|
_ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
_goal: Goal<'tcx, Self>,
|
_goal: Goal<'tcx, Self>,
|
||||||
assumption: ty::Predicate<'tcx>,
|
assumption: ty::Predicate<'tcx>,
|
||||||
) -> Result<Certainty, NoSolution> {
|
) -> QueryResult<'tcx> {
|
||||||
if let Some(_poly_trait_pred) = assumption.to_opt_poly_trait_pred() {
|
if let Some(_poly_trait_pred) = assumption.to_opt_poly_trait_pred() {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue