]>
Commit | Line | Data |
---|---|---|
add651ee FG |
1 | //! Computes a normalizes-to (projection) goal for inherent associated types, |
2 | //! `#![feature(inherent_associated_type)]`. Since astconv already determines | |
3 | //! which impl the IAT is being projected from, we just: | |
4 | //! 1. instantiate substs, | |
5 | //! 2. equate the self type, and | |
6 | //! 3. instantiate and register where clauses. | |
7 | use rustc_middle::traits::solve::{Certainty, Goal, QueryResult}; | |
8 | use rustc_middle::ty; | |
9 | ||
10 | use super::EvalCtxt; | |
11 | ||
12 | impl<'tcx> EvalCtxt<'_, 'tcx> { | |
13 | pub(super) fn normalize_inherent_associated_type( | |
14 | &mut self, | |
15 | goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>, | |
16 | ) -> QueryResult<'tcx> { | |
17 | let tcx = self.tcx(); | |
18 | let inherent = goal.predicate.projection_ty; | |
19 | let expected = goal.predicate.term.ty().expect("inherent consts are treated separately"); | |
20 | ||
21 | let impl_def_id = tcx.parent(inherent.def_id); | |
22 | let impl_substs = self.fresh_args_for_item(impl_def_id); | |
23 | ||
24 | // Equate impl header and add impl where clauses | |
25 | self.eq( | |
26 | goal.param_env, | |
27 | inherent.self_ty(), | |
28 | tcx.type_of(impl_def_id).instantiate(tcx, impl_substs), | |
29 | )?; | |
30 | ||
31 | // Equate IAT with the RHS of the project goal | |
32 | let inherent_substs = inherent.rebase_inherent_args_onto_impl(impl_substs, tcx); | |
33 | self.eq( | |
34 | goal.param_env, | |
35 | expected, | |
36 | tcx.type_of(inherent.def_id).instantiate(tcx, inherent_substs), | |
37 | ) | |
38 | .expect("expected goal term to be fully unconstrained"); | |
39 | ||
40 | // Check both where clauses on the impl and IAT | |
41 | self.add_goals( | |
42 | tcx.predicates_of(inherent.def_id) | |
43 | .instantiate(tcx, inherent_substs) | |
44 | .into_iter() | |
45 | .map(|(pred, _)| goal.with(tcx, pred)), | |
46 | ); | |
47 | ||
48 | self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) | |
49 | } | |
50 | } |