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