summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_trait_selection/src/solve/inherent_projection.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_trait_selection/src/solve/inherent_projection.rs')
-rw-r--r--compiler/rustc_trait_selection/src/solve/inherent_projection.rs50
1 files changed, 50 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/inherent_projection.rs b/compiler/rustc_trait_selection/src/solve/inherent_projection.rs
new file mode 100644
index 000000000..28fe59b7f
--- /dev/null
+++ b/compiler/rustc_trait_selection/src/solve/inherent_projection.rs
@@ -0,0 +1,50 @@
+//! 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, QueryResult};
+use rustc_middle::ty;
+
+use super::EvalCtxt;
+
+impl<'tcx> EvalCtxt<'_, 'tcx> {
+ pub(super) fn normalize_inherent_associated_type(
+ &mut self,
+ goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
+ ) -> QueryResult<'tcx> {
+ let tcx = self.tcx();
+ let inherent = goal.predicate.projection_ty;
+ 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
+ self.add_goals(
+ 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)
+ }
+}