22//! Doing this via a separate goal is called "deferred alias relation" and part
33//! of our more general approach to "lazy normalization".
44//!
5- //! This goal, e.g. `A alias-relate B`, may be satisfied by one of three branches:
6- //! * normalizes-to: If `A` is a projection, we can prove the equivalent
7- //! projection predicate with B as the right-hand side of the projection.
8- //! This goal is computed in both directions, if both are aliases.
9- //! * subst-relate: Equate `A` and `B` by their substs, if they're both
10- //! aliases with the same def-id.
11- //! * bidirectional-normalizes-to: If `A` and `B` are both projections, and both
12- //! may apply, then we can compute the "intersection" of both normalizes-to by
13- //! performing them together. This is used specifically to resolve ambiguities.
5+ //! This is done by first normalizing both sides of the goal, ending up in
6+ //! either a concrete type, rigid projection, opaque, or an infer variable.
7+ //! These are related further, described best with inline comments below.
8+
149use super :: EvalCtxt ;
1510use rustc_infer:: infer:: DefineOpaqueTypes ;
1611use rustc_infer:: traits:: query:: NoSolution ;
@@ -45,11 +40,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
4540 self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
4641 }
4742
43+ // 1. When we have an alias being related to an infer var, then assign
44+ // the type (or const) of the alias to the infer var.
45+ // 2. When we have an opaque being related to a rigid type (which, due to 1,
46+ // is not an infer var), then assign the hidden type of the opaque to be
47+ // the rigid type.
48+ // 3. Otherwise, a rigid projection does not equal a concrete type ever.
4849 ( Some ( alias) , None ) => {
4950 if rhs. is_infer ( ) {
5051 self . relate ( param_env, lhs, variance, rhs) ?;
5152 self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
5253 } else if alias. is_opaque ( tcx) {
54+ // FIXME: This doesn't account for variance.
5355 self . define_opaque ( param_env, alias, rhs)
5456 } else {
5557 Err ( NoSolution )
@@ -60,6 +62,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
6062 self . relate ( param_env, lhs, variance, rhs) ?;
6163 self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
6264 } else if alias. is_opaque ( tcx) {
65+ // FIXME: This doesn't account for variance.
6366 self . define_opaque ( param_env, alias, lhs)
6467 } else {
6568 Err ( NoSolution )
@@ -72,6 +75,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
7275 }
7376 }
7477
78+ // FIXME: This needs a name that reflects that it's okay to bottom-out with an inference var.
7579 /// Normalize the `term` to equate it later. This does not define opaque types.
7680 #[ instrument( level = "debug" , skip( self , param_env) , ret) ]
7781 fn try_normalize_term (
0 commit comments