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, described best with inline comments below.
8
+
14
9
use super :: EvalCtxt ;
15
10
use rustc_infer:: infer:: DefineOpaqueTypes ;
16
11
use rustc_infer:: traits:: query:: NoSolution ;
@@ -45,11 +40,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
45
40
self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
46
41
}
47
42
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.
48
49
( Some ( alias) , None ) => {
49
50
if rhs. is_infer ( ) {
50
51
self . relate ( param_env, lhs, variance, rhs) ?;
51
52
self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
52
53
} else if alias. is_opaque ( tcx) {
54
+ // FIXME: This doesn't account for variance.
53
55
self . define_opaque ( param_env, alias, rhs)
54
56
} else {
55
57
Err ( NoSolution )
@@ -60,6 +62,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
60
62
self . relate ( param_env, lhs, variance, rhs) ?;
61
63
self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
62
64
} else if alias. is_opaque ( tcx) {
65
+ // FIXME: This doesn't account for variance.
63
66
self . define_opaque ( param_env, alias, lhs)
64
67
} else {
65
68
Err ( NoSolution )
@@ -72,6 +75,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
72
75
}
73
76
}
74
77
78
+ // FIXME: This needs a name that reflects that it's okay to bottom-out with an inference var.
75
79
/// Normalize the `term` to equate it later. This does not define opaque types.
76
80
#[ instrument( level = "debug" , skip( self , param_env) , ret) ]
77
81
fn try_normalize_term (
0 commit comments