add eq
to InferCtxtExt
This commit is contained in:
parent
660c28391c
commit
9a757d6ee4
@ -1,11 +1,28 @@
|
||||
use rustc_infer::infer::at::ToTrace;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_infer::infer::{InferCtxt, InferOk};
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::DUMMY_SP;
|
||||
|
||||
use super::Goal;
|
||||
|
||||
/// Methods used inside of the canonical queries of the solver.
|
||||
///
|
||||
/// Most notably these do not care about diagnostics information.
|
||||
/// If you find this while looking for methods to use outside of the
|
||||
/// solver, you may look at the implementation of these method for
|
||||
/// help.
|
||||
pub(super) trait InferCtxtExt<'tcx> {
|
||||
fn next_ty_infer(&self) -> Ty<'tcx>;
|
||||
|
||||
fn eq<T: ToTrace<'tcx>>(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
lhs: T,
|
||||
rhs: T,
|
||||
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>;
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
@ -15,4 +32,23 @@ fn next_ty_infer(&self) -> Ty<'tcx> {
|
||||
span: DUMMY_SP,
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, param_env), ret)]
|
||||
fn eq<T: ToTrace<'tcx>>(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
lhs: T,
|
||||
rhs: T,
|
||||
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
|
||||
self.at(&ObligationCause::dummy(), param_env)
|
||||
.define_opaque_types(false)
|
||||
.eq(lhs, rhs)
|
||||
.map(|InferOk { value: (), obligations }| {
|
||||
obligations.into_iter().map(|o| o.into()).collect()
|
||||
})
|
||||
.map_err(|e| {
|
||||
debug!(?e, "failed to equate");
|
||||
NoSolution
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
use crate::traits::{specialization_graph, translate_substs};
|
||||
|
||||
use super::assembly::{self, Candidate, CandidateSource};
|
||||
use super::infcx_ext::InferCtxtExt;
|
||||
use super::{Certainty, EvalCtxt, Goal, QueryResult};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::{InferCtxt, InferOk};
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_infer::traits::specialization_graph::LeafDef;
|
||||
use rustc_infer::traits::{ObligationCause, Reveal};
|
||||
use rustc_infer::traits::Reveal;
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||
use rustc_middle::ty::ProjectionPredicate;
|
||||
use rustc_middle::ty::TypeVisitable;
|
||||
@ -112,14 +113,7 @@ fn consider_impl_candidate(
|
||||
let impl_substs = ecx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
|
||||
let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs);
|
||||
|
||||
let Ok(InferOk { obligations, .. }) = ecx.infcx
|
||||
.at(&ObligationCause::dummy(), goal.param_env)
|
||||
.define_opaque_types(false)
|
||||
.eq(goal_trait_ref, impl_trait_ref)
|
||||
.map_err(|e| debug!("failed to equate trait refs: {e:?}"))
|
||||
else {
|
||||
return Err(NoSolution)
|
||||
};
|
||||
let mut nested_goals = ecx.infcx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
|
||||
let where_clause_bounds = tcx
|
||||
.predicates_of(impl_def_id)
|
||||
.instantiate(tcx, impl_substs)
|
||||
@ -127,8 +121,7 @@ fn consider_impl_candidate(
|
||||
.into_iter()
|
||||
.map(|pred| goal.with(tcx, pred));
|
||||
|
||||
let nested_goals =
|
||||
obligations.into_iter().map(|o| o.into()).chain(where_clause_bounds).collect();
|
||||
nested_goals.extend(where_clause_bounds);
|
||||
let trait_ref_certainty = ecx.evaluate_all(nested_goals)?;
|
||||
|
||||
let Some(assoc_def) = fetch_eligible_assoc_item_def(
|
||||
@ -185,16 +178,8 @@ fn consider_impl_candidate(
|
||||
ty.map_bound(|ty| ty.into())
|
||||
};
|
||||
|
||||
let Ok(InferOk { obligations, .. }) = ecx.infcx
|
||||
.at(&ObligationCause::dummy(), goal.param_env)
|
||||
.define_opaque_types(false)
|
||||
.eq(goal.predicate.term, term.subst(tcx, substs))
|
||||
.map_err(|e| debug!("failed to equate trait refs: {e:?}"))
|
||||
else {
|
||||
return Err(NoSolution);
|
||||
};
|
||||
|
||||
let nested_goals = obligations.into_iter().map(|o| o.into()).collect();
|
||||
let nested_goals =
|
||||
ecx.infcx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs))?;
|
||||
let rhs_certainty = ecx.evaluate_all(nested_goals)?;
|
||||
|
||||
Ok(trait_ref_certainty.unify_and(rhs_certainty))
|
||||
|
@ -3,11 +3,10 @@
|
||||
use std::iter;
|
||||
|
||||
use super::assembly::{self, Candidate, CandidateSource};
|
||||
use super::infcx_ext::InferCtxtExt;
|
||||
use super::{Certainty, EvalCtxt, Goal, QueryResult};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::InferOk;
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||
use rustc_middle::ty::TraitPredicate;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
@ -45,24 +44,15 @@ fn consider_impl_candidate(
|
||||
let impl_substs = ecx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
|
||||
let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs);
|
||||
|
||||
let Ok(InferOk { obligations, .. }) = ecx.infcx
|
||||
.at(&ObligationCause::dummy(), goal.param_env)
|
||||
.define_opaque_types(false)
|
||||
.eq(goal.predicate.trait_ref, impl_trait_ref)
|
||||
.map_err(|e| debug!("failed to equate trait refs: {e:?}"))
|
||||
else {
|
||||
return Err(NoSolution);
|
||||
};
|
||||
let mut nested_goals =
|
||||
ecx.infcx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
|
||||
let where_clause_bounds = tcx
|
||||
.predicates_of(impl_def_id)
|
||||
.instantiate(tcx, impl_substs)
|
||||
.predicates
|
||||
.into_iter()
|
||||
.map(|pred| goal.with(tcx, pred));
|
||||
|
||||
let nested_goals =
|
||||
obligations.into_iter().map(|o| o.into()).chain(where_clause_bounds).collect();
|
||||
|
||||
nested_goals.extend(where_clause_bounds);
|
||||
ecx.evaluate_all(nested_goals)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user