Move some InferCtxt methods to EvalCtxt in new solver
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
use crate::traits::{specialization_graph, translate_substs};
|
||||
|
||||
use super::assembly;
|
||||
use super::infcx_ext::InferCtxtExt;
|
||||
use super::trait_goals::structural_traits;
|
||||
use super::{Certainty, EvalCtxt, Goal, QueryResult};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
@@ -13,12 +12,11 @@ use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_infer::traits::specialization_graph::LeafDef;
|
||||
use rustc_infer::traits::Reveal;
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||
use rustc_middle::ty::ProjectionPredicate;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{ir::TypeVisitor, ProjectionPredicate, TypeSuperVisitable};
|
||||
use rustc_middle::ty::{ToPredicate, TypeVisitable};
|
||||
use rustc_span::{sym, DUMMY_SP};
|
||||
use std::iter;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
pub(super) fn compute_projection_goal(
|
||||
@@ -38,8 +36,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
} else {
|
||||
let predicate = goal.predicate;
|
||||
let unconstrained_rhs = match predicate.term.unpack() {
|
||||
ty::TermKind::Ty(_) => self.infcx.next_ty_infer().into(),
|
||||
ty::TermKind::Const(ct) => self.infcx.next_const_infer(ct.ty()).into(),
|
||||
ty::TermKind::Ty(_) => self.next_ty_infer().into(),
|
||||
ty::TermKind::Const(ct) => self.next_const_infer(ct.ty()).into(),
|
||||
};
|
||||
let unconstrained_predicate = ty::Clause::Projection(ProjectionPredicate {
|
||||
projection_ty: goal.predicate.projection_ty,
|
||||
@@ -49,8 +47,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
this.evaluate_goal(goal.with(this.tcx(), unconstrained_predicate))
|
||||
})?;
|
||||
|
||||
let nested_eq_goals =
|
||||
self.infcx.eq(goal.param_env, unconstrained_rhs, predicate.term)?;
|
||||
let nested_eq_goals = self.eq(goal.param_env, unconstrained_rhs, predicate.term)?;
|
||||
let eval_certainty = self.evaluate_all(nested_eq_goals)?;
|
||||
self.make_canonical_response(normalize_certainty.unify_and(eval_certainty))
|
||||
}
|
||||
@@ -65,73 +62,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
result
|
||||
}
|
||||
|
||||
/// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`.
|
||||
///
|
||||
/// This is the case if the `term` is an inference variable in the innermost universe
|
||||
/// and does not occur in any other part of the predicate.
|
||||
fn term_is_fully_unconstrained(&self, goal: Goal<'tcx, ProjectionPredicate<'tcx>>) -> bool {
|
||||
let infcx = self.infcx;
|
||||
let term_is_infer = match goal.predicate.term.unpack() {
|
||||
ty::TermKind::Ty(ty) => {
|
||||
if let &ty::Infer(ty::TyVar(vid)) = ty.kind() {
|
||||
match infcx.probe_ty_var(vid) {
|
||||
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
|
||||
Err(universe) => universe == infcx.universe(),
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
ty::TermKind::Const(ct) => {
|
||||
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() {
|
||||
match self.infcx.probe_const_var(vid) {
|
||||
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
|
||||
Err(universe) => universe == infcx.universe(),
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Guard against `<T as Trait<?0>>::Assoc = ?0>`.
|
||||
struct ContainsTerm<'tcx> {
|
||||
term: ty::Term<'tcx>,
|
||||
}
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> {
|
||||
type BreakTy = ();
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
if t.needs_infer() {
|
||||
if ty::Term::from(t) == self.term {
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
if c.needs_infer() {
|
||||
if ty::Term::from(c) == self.term {
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
c.super_visit_with(self)
|
||||
}
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut visitor = ContainsTerm { term: goal.predicate.term };
|
||||
|
||||
term_is_infer
|
||||
&& goal.predicate.projection_ty.visit_with(&mut visitor).is_continue()
|
||||
&& goal.param_env.visit_with(&mut visitor).is_continue()
|
||||
}
|
||||
|
||||
/// After normalizing the projection to `normalized_alias` with the given
|
||||
/// `normalization_certainty`, constrain the inference variable `term` to it
|
||||
/// and return a query response.
|
||||
@@ -145,7 +75,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
//
|
||||
// It can however be ambiguous when the `normalized_alias` contains a projection.
|
||||
let nested_goals = self
|
||||
.infcx
|
||||
.eq(goal.param_env, goal.predicate.term, normalized_alias.into())
|
||||
.expect("failed to unify with unconstrained term");
|
||||
let rhs_certainty =
|
||||
@@ -177,10 +106,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||
if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
|
||||
&& poly_projection_pred.projection_def_id() == goal.predicate.def_id()
|
||||
{
|
||||
ecx.infcx.probe(|_| {
|
||||
ecx.probe(|ecx| {
|
||||
let assumption_projection_pred =
|
||||
ecx.infcx.instantiate_binder_with_infer(poly_projection_pred);
|
||||
let mut nested_goals = ecx.infcx.eq(
|
||||
ecx.instantiate_binder_with_infer(poly_projection_pred);
|
||||
let mut nested_goals = ecx.eq(
|
||||
goal.param_env,
|
||||
goal.predicate.projection_ty,
|
||||
assumption_projection_pred.projection_ty,
|
||||
@@ -215,11 +144,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
ecx.infcx.probe(|_| {
|
||||
let impl_substs = ecx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
|
||||
ecx.probe(|ecx| {
|
||||
let impl_substs = ecx.fresh_substs_for_item(impl_def_id);
|
||||
let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs);
|
||||
|
||||
let mut nested_goals = ecx.infcx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
|
||||
let mut nested_goals = ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
|
||||
let where_clause_bounds = tcx
|
||||
.predicates_of(impl_def_id)
|
||||
.instantiate(tcx, impl_substs)
|
||||
@@ -367,7 +296,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let tcx = ecx.tcx();
|
||||
ecx.infcx.probe(|_| {
|
||||
ecx.probe(|ecx| {
|
||||
let metadata_ty = match goal.predicate.self_ty().kind() {
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
@@ -546,8 +475,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let discriminant = goal.predicate.self_ty().discriminant_ty(ecx.tcx());
|
||||
ecx.infcx
|
||||
.probe(|_| ecx.eq_term_and_make_canonical_response(goal, Certainty::Yes, discriminant))
|
||||
ecx.probe(|ecx| ecx.eq_term_and_make_canonical_response(goal, Certainty::Yes, discriminant))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user