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
38 debug_assert!(
43 lhs.to_alias_term().is_some()
44 || rhs.to_alias_term().is_some()
45 || lhs.is_error()
46 || rhs.is_error()
47 );
48
49 let lhs = if let Some(alias) = lhs.to_alias_term() {
51 let term = self.next_term_infer_of_kind(lhs);
52 self.add_normalizes_to_goal(goal.with(cx, ty::NormalizesTo { alias, term }));
53 term
54 } else {
55 lhs
56 };
57
58 let rhs = if let Some(alias) = rhs.to_alias_term() {
60 let term = self.next_term_infer_of_kind(rhs);
61 self.add_normalizes_to_goal(goal.with(cx, ty::NormalizesTo { alias, term }));
62 term
63 } else {
64 rhs
65 };
66
67 self.inspect.make_canonical_response(Certainty::AMBIGUOUS);
72
73 self.try_evaluate_added_goals()?;
75 let lhs = self.resolve_vars_if_possible(lhs);
76 let rhs = self.resolve_vars_if_possible(rhs);
77 trace!(?lhs, ?rhs);
78
79 let variance = match direction {
80 ty::AliasRelationDirection::Equate => ty::Invariant,
81 ty::AliasRelationDirection::Subtype => ty::Covariant,
82 };
83 match (lhs.to_alias_term(), rhs.to_alias_term()) {
84 (None, None) => {
85 self.relate(param_env, lhs, variance, rhs)?;
86 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
87 }
88
89 (Some(alias), None) => {
90 self.relate_rigid_alias_non_alias(param_env, alias, variance, rhs)?;
91 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
92 }
93 (None, Some(alias)) => {
94 self.relate_rigid_alias_non_alias(
95 param_env,
96 alias,
97 variance.xform(ty::Contravariant),
98 lhs,
99 )?;
100 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
101 }
102
103 (Some(alias_lhs), Some(alias_rhs)) => {
104 self.relate(param_env, alias_lhs, variance, alias_rhs)?;
105 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
106 }
107 }
108 }
109}