1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
//! Computes a normalizes-to (projection) goal for inherent associated types,
//! `#![feature(inherent_associated_type)]`. Since HIR ty lowering already determines
//! which impl the IAT is being projected from, we just:
//! 1. instantiate generic parameters,
//! 2. equate the self type, and
//! 3. instantiate and register where clauses.
use rustc_type_ir::{self as ty, Interner};
use crate::delegate::SolverDelegate;
use crate::solve::{Certainty, EvalCtxt, Goal, GoalSource, QueryResult};
impl<D, I> EvalCtxt<'_, D>
where
D: SolverDelegate<Interner = I>,
I: Interner,
{
pub(super) fn normalize_inherent_associated_type(
&mut self,
goal: Goal<I, ty::NormalizesTo<I>>,
) -> QueryResult<I> {
let cx = self.cx();
let inherent = goal.predicate.alias.expect_ty(cx);
let impl_def_id = cx.parent(inherent.def_id);
let impl_args = self.fresh_args_for_item(impl_def_id);
// Equate impl header and add impl where clauses
self.eq(
goal.param_env,
inherent.self_ty(),
cx.type_of(impl_def_id).instantiate(cx, impl_args),
)?;
// Equate IAT with the RHS of the project goal
let inherent_args = inherent.rebase_inherent_args_onto_impl(impl_args, cx);
// Check both where clauses on the impl and IAT
//
// FIXME(-Znext-solver=coinductive): I think this should be split
// and we tag the impl bounds with `GoalSource::ImplWhereBound`?
// Right not this includes both the impl and the assoc item where bounds,
// and I don't think the assoc item where-bounds are allowed to be coinductive.
self.add_goals(
GoalSource::Misc,
cx.predicates_of(inherent.def_id)
.iter_instantiated(cx, inherent_args)
.map(|pred| goal.with(cx, pred)),
);
let normalized = cx.type_of(inherent.def_id).instantiate(cx, inherent_args);
self.instantiate_normalizes_to_term(goal, normalized.into());
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
}