rustc_next_trait_solver/solve/project_goals/
inherent.rs1use rustc_type_ir::solve::{NoSolutionOrRerunNonErased, QueryResultOrRerunNonErased};
9use rustc_type_ir::{self as ty, Interner, Unnormalized};
10
11use crate::delegate::SolverDelegate;
12use crate::solve::{Certainty, EvalCtxt, Goal, GoalSource};
13
14impl<D, I> EvalCtxt<'_, D>
15where
16 D: SolverDelegate<Interner = I>,
17 I: Interner,
18{
19 pub(super) fn normalize_inherent_associated_term(
20 &mut self,
21 goal: Goal<I, ty::ProjectionClause<I>>,
22 ) -> QueryResultOrRerunNonErased<I> {
23 let cx = self.cx();
24 let def_id = goal.predicate.projection_term.expect_inherent_def_id();
25 let (inherent_kind, inherent_args) =
26 self.convert_inherent_self_to_impl(goal.param_env, goal.predicate.projection_term)?;
27
28 self.add_goals(
38 GoalSource::Misc,
39 cx.clauses_of(def_id.into())
40 .iter_instantiated(cx, inherent_args)
41 .map(Unnormalized::skip_norm_wip)
42 .map(|clause| goal.with(cx, clause)),
43 )?;
44
45 let normalized: I::Term = match inherent_kind {
46 ty::AliasTermKind::InherentTy { def_id } => {
47 let inherent = cx.type_of(def_id.into()).instantiate(cx, inherent_args);
48 let inherent = self.normalize(GoalSource::Misc, goal.param_env, inherent)?;
49 inherent.into()
50 }
51 ty::AliasTermKind::InherentConstImpl { def_id }
52 if let Some(inherent) =
53 cx.const_of_item(ty::AliasConstKind::InherentImpl { def_id }) =>
54 {
55 let inherent = inherent.instantiate(cx, inherent_args);
56 let normalized_ct = self.normalize(GoalSource::Misc, goal.param_env, inherent)?;
57 let normalized = normalized_ct.into();
58 let term = ty::AliasTerm::new_from_args(cx, inherent_kind, inherent_args);
59 self.push_const_arg_has_type_goal(goal.param_env, term, normalized)?;
60 normalized
61 }
62 ty::AliasTermKind::InherentConstImpl { .. } => {
63 let term = ty::AliasTerm::new_from_args(cx, inherent_kind, inherent_args);
64 return self.evaluate_const_and_instantiate_projection_term(
68 goal.param_env,
69 term,
70 goal.predicate.term,
71 term.expect_ct(),
72 );
73 }
74 kind => {
::core::panicking::panic_fmt(format_args!("expected inherent alias, found {0:?}",
kind));
}panic!("expected inherent alias, found {kind:?}"),
75 };
76
77 self.eq(goal.param_env, goal.predicate.term, normalized)?;
78 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
79 }
80
81 fn convert_inherent_self_to_impl(
82 &mut self,
83 param_env: I::ParamEnv,
84 term: ty::AliasTerm<I>,
85 ) -> Result<(ty::AliasTermKind<I>, I::GenericArgs), NoSolutionOrRerunNonErased> {
86 match term.kind {
87 ty::AliasTermKind::InherentTy { .. } | ty::AliasTermKind::InherentConstSelf { .. } => {
88 let cx = self.cx();
89 let def_id = term.expect_inherent_def_id();
90 let impl_def_id = cx.inherent_alias_term_parent(def_id);
91 let impl_args = self.fresh_args_for_item(impl_def_id.into());
92
93 self.eq(
95 param_env,
96 term.self_ty(),
97 cx.type_of(impl_def_id.into()).instantiate(cx, impl_args).skip_norm_wip(),
98 )?;
99
100 let inherent_args = term.rebase_inherent_args_onto_impl(impl_args, cx);
102
103 let kind = match term.kind {
104 ty::AliasTermKind::InherentTy { def_id } => {
105 ty::AliasTermKind::InherentTy { def_id }
106 }
107 ty::AliasTermKind::InherentConstSelf { def_id } => {
108 ty::AliasTermKind::InherentConstImpl { def_id }
109 }
110 _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
111 };
112
113 Ok((kind, inherent_args))
114 }
115 ty::AliasTermKind::InherentConstImpl { .. } => Ok((term.kind, term.args)),
116 kind => {
::core::panicking::panic_fmt(format_args!("expected inherent alias, found {0:?}",
kind));
}panic!("expected inherent alias, found {kind:?}"),
117 }
118 }
119}