2
2
//! Doing this via a separate goal is called "deferred alias relation" and part
3
3
//! of our more general approach to "lazy normalization".
4
4
//!
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 according to the rules below:
8
+ //!
9
+ //! (1.) If we end up with a rigid projection and a rigid projection, then we
10
+ //! relate those projections structurally.
11
+ //!
12
+ //! (2.) If we end up with a rigid projection and an alias, then the opaque will
13
+ //! have its hidden type defined to be that rigid projection.
14
+ //!
15
+ //! (3.) If we end up with an opaque and an opaque, then we assemble two
16
+ //! candidates, one defining the LHS to be the hidden type of the RHS, and vice
17
+ //! versa.
18
+ //!
19
+ //! (4.) If we end up with an infer var and an opaque or rigid projection, then
20
+ //! we assign the alias to the infer var.
21
+ //!
22
+ //! (5.) If we end up with an opaque and a rigid (non-projection) type, then we
23
+ //! define the hidden type of the opaque to be the rigid type.
24
+ //!
25
+ //! (6.) Otherwise, if we end with two rigid (non-projection) or infer types,
26
+ //! relate them structurally.
27
+
14
28
use super :: { EvalCtxt , GoalSource } ;
15
29
use rustc_infer:: infer:: DefineOpaqueTypes ;
16
30
use rustc_infer:: traits:: query:: NoSolution ;
@@ -50,6 +64,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
50
64
self . relate ( param_env, lhs, variance, rhs) ?;
51
65
self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
52
66
} else if alias. is_opaque ( tcx) {
67
+ // FIXME: This doesn't account for variance.
53
68
self . define_opaque ( param_env, alias, rhs)
54
69
} else {
55
70
Err ( NoSolution )
@@ -60,6 +75,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
60
75
self . relate ( param_env, lhs, variance, rhs) ?;
61
76
self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
62
77
} else if alias. is_opaque ( tcx) {
78
+ // FIXME: This doesn't account for variance.
63
79
self . define_opaque ( param_env, alias, lhs)
64
80
} else {
65
81
Err ( NoSolution )
@@ -72,6 +88,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
72
88
}
73
89
}
74
90
91
+ // FIXME: This needs a name that reflects that it's okay to bottom-out with an inference var.
75
92
/// Normalize the `term` to equate it later. This does not define opaque types.
76
93
#[ instrument( level = "debug" , skip( self , param_env) , ret) ]
77
94
fn try_normalize_term (
0 commit comments