rustc_next_trait_solver/solve/
alias_relate.rs1use rustc_type_ir::inherent::*;
19use rustc_type_ir::solve::GoalSource;
20use rustc_type_ir::{self as ty, Interner};
21use tracing::{instrument, trace};
22
23use crate::delegate::SolverDelegate;
24use crate::solve::{Certainty, EvalCtxt, Goal, QueryResult};
25
26impl<D, I> EvalCtxt<'_, D>
27where
28 D: SolverDelegate<Interner = I>,
29 I: Interner,
30{
31 #[instrument(level = "trace", skip(self), ret)]
32 pub(super) fn compute_alias_relate_goal(
33 &mut self,
34 goal: Goal<I, (I::Term, I::Term, ty::AliasRelationDirection)>,
35 ) -> QueryResult<I> {
36 let cx = self.cx();
37 let Goal { param_env, predicate: (lhs, rhs, direction) } = goal;
38
39 debug_assert!(
44 lhs.to_alias_term().is_some()
45 || rhs.to_alias_term().is_some()
46 || lhs.is_error()
47 || rhs.is_error()
48 );
49
50 let lhs = if let Some(alias) = lhs.to_alias_term() {
52 let term = self.next_term_infer_of_kind(lhs);
53 self.add_goal(
54 GoalSource::TypeRelating,
55 goal.with(cx, ty::NormalizesTo { alias, term }),
56 );
57 term
58 } else {
59 lhs
60 };
61
62 let rhs = if let Some(alias) = rhs.to_alias_term() {
64 let term = self.next_term_infer_of_kind(rhs);
65 self.add_goal(
66 GoalSource::TypeRelating,
67 goal.with(cx, ty::NormalizesTo { alias, term }),
68 );
69 term
70 } else {
71 rhs
72 };
73
74 self.inspect.make_canonical_response(Certainty::AMBIGUOUS);
79
80 self.try_evaluate_added_goals()?;
82 let lhs = self.resolve_vars_if_possible(lhs);
83 let rhs = self.resolve_vars_if_possible(rhs);
84 trace!(?lhs, ?rhs);
85
86 let variance = match direction {
87 ty::AliasRelationDirection::Equate => ty::Invariant,
88 ty::AliasRelationDirection::Subtype => ty::Covariant,
89 };
90 match (lhs.to_alias_term(), rhs.to_alias_term()) {
91 (None, None) => {
92 self.relate(param_env, lhs, variance, rhs)?;
93 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
94 }
95
96 (Some(alias), None) => {
97 self.relate_rigid_alias_non_alias(param_env, alias, variance, rhs)?;
98 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
99 }
100 (None, Some(alias)) => {
101 self.relate_rigid_alias_non_alias(
102 param_env,
103 alias,
104 variance.xform(ty::Contravariant),
105 lhs,
106 )?;
107 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
108 }
109
110 (Some(alias_lhs), Some(alias_rhs)) => {
111 self.relate(param_env, alias_lhs, variance, alias_rhs)?;
112 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
113 }
114 }
115 }
116}