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
56
|
//! Computes a normalizes-to (projection) goal for inherent associated types,
//! `#![feature(inherent_associated_type)]`. Since astconv already determines
//! which impl the IAT is being projected from, we just:
//! 1. instantiate substs,
//! 2. equate the self type, and
//! 3. instantiate and register where clauses.
use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, QueryResult};
use rustc_middle::ty;
use crate::solve::EvalCtxt;
impl<'tcx> EvalCtxt<'_, 'tcx> {
pub(super) fn normalize_inherent_associated_type(
&mut self,
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
) -> QueryResult<'tcx> {
let tcx = self.tcx();
let inherent = goal.predicate.alias;
let expected = goal.predicate.term.ty().expect("inherent consts are treated separately");
let impl_def_id = tcx.parent(inherent.def_id);
let impl_substs = self.fresh_args_for_item(impl_def_id);
// Equate impl header and add impl where clauses
self.eq(
goal.param_env,
inherent.self_ty(),
tcx.type_of(impl_def_id).instantiate(tcx, impl_substs),
)?;
// Equate IAT with the RHS of the project goal
let inherent_substs = inherent.rebase_inherent_args_onto_impl(impl_substs, tcx);
self.eq(
goal.param_env,
expected,
tcx.type_of(inherent.def_id).instantiate(tcx, inherent_substs),
)
.expect("expected goal term to be fully unconstrained");
// 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,
tcx.predicates_of(inherent.def_id)
.instantiate(tcx, inherent_substs)
.into_iter()
.map(|(pred, _)| goal.with(tcx, pred)),
);
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
}
|