1
1
use formality_types:: {
2
- cast:: { Downcast , Downcasted , Upcast , Upcasted } ,
2
+ cast:: { Downcast , Upcast , Upcasted } ,
3
3
collections:: { Deduplicate , Set } ,
4
4
grammar:: {
5
5
AliasTy , AtomicRelation , InferenceVar , Parameter , PlaceholderVar , RigidTy , Substitution ,
@@ -79,27 +79,20 @@ judgment_fn! {
79
79
(
80
80
( if let None = t. downcast:: <Variable >( ) )
81
81
( equate_variable( program, env, assumptions, v, t) => ( env, c) )
82
- ----------------------------- ( "existential-l " )
82
+ ----------------------------- ( "existential-nonvar " )
83
83
( prove_ty_eq( program, env, assumptions, Variable :: InferenceVar ( v) , t) => ( env, c) )
84
84
)
85
85
86
- (
87
- ( if let None = t. downcast:: <Variable >( ) )
88
- ( equate_variable( program, env, assumptions, v, t) => ( env, c) )
89
- ----------------------------- ( "existential-r" )
90
- ( prove_ty_eq( program, env, assumptions, t, Variable :: InferenceVar ( v) ) => ( env, c) )
91
- )
92
-
93
86
(
94
87
// Map the higher rank variable to the lower rank one.
95
88
( let ( a, b) = env. order_by_universe( l, r) )
96
- ----------------------------- ( "existential-both " )
89
+ ----------------------------- ( "existential-existential " )
97
90
( prove_ty_eq( _program, env, _assumptions, Variable :: InferenceVar ( l) , Variable :: InferenceVar ( r) ) => ( env, ( b, a) ) )
98
91
)
99
92
100
93
(
101
94
( if env. universe( p) < env. universe( v) )
102
- ----------------------------- ( "existential-vs- placeholder" )
95
+ ----------------------------- ( "existential-placeholder" )
103
96
( prove_ty_eq( _program, env, _assumptions, Variable :: InferenceVar ( v) , Variable :: PlaceholderVar ( p) ) => ( env, ( v, p) ) )
104
97
)
105
98
@@ -124,9 +117,14 @@ fn equate_variable(
124
117
let span = tracing:: debug_span!( "equate_variable" , ?x, ?p, ?env) ;
125
118
let _guard = span. enter ( ) ;
126
119
127
- let fvs = p. free_variables ( ) . deduplicate ( ) ;
120
+ // Preconditions:
121
+ // * Environment contains all free variables
122
+ // * `p` is some compound type, not a variable
123
+ // (variables are handled via special rules above)
124
+ env. assert_encloses ( ( x, ( & assumptions, & p) ) ) ;
125
+ assert ! ( !p. is_a:: <Variable >( ) ) ;
128
126
129
- env . assert_encloses ( ( x , & fvs) ) ;
127
+ let fvs = p . free_variables ( ) . deduplicate ( ) ;
130
128
131
129
// Ensure that `x` passes the occurs check for the free variables in `p`.
132
130
if occurs_in ( x, & fvs) {
@@ -154,14 +152,18 @@ fn equate_variable(
154
152
155
153
// Introduce the following constraints:
156
154
//
157
- // * `fv = universe_subst(fv)` for each free variable `fv` in `p` (e.g., `Y => Z` in our example above)
155
+ // * `fv = universe_subst(fv)` for each free existential variable `fv` in `p` (e.g., `Y => Z` in our example above)
158
156
// * `x = universe_subst(p)` (e.g., `Vec<Z>` in our example above)
159
157
let constraints: Constraints = universe_subst
160
158
. iter ( )
161
159
. filter ( |( v, _) | v. is_a :: < InferenceVar > ( ) )
162
160
. chain ( Some ( ( x, universe_subst. apply ( & p) ) . upcast ( ) ) )
163
161
. collect ( ) ;
164
162
163
+ // For each placeholder variable that we replaced with an inference variable
164
+ // above, we now have to prove that goal. e.g., if we had `X = Vec<!Y>`, we would replace `!Y` with `?Z`
165
+ // (where `?Z` is in a lower universe than `X`), but now we must prove that `!Y = ?Z`
166
+ // (this may be posible due to assumptions).
165
167
let goals: Wcs = universe_subst
166
168
. iter ( )
167
169
. filter ( |( v, _) | v. is_a :: < PlaceholderVar > ( ) )
0 commit comments