3 use super::unify
::RelationResult
;
5 use chalk_integration
::interner
::ChalkIr
;
6 use chalk_integration
::{arg, lifetime, ty}
;
8 // We just use a vec of 20 `Invariant`, since this is zipped and no substs are
12 impl UnificationDatabase
<ChalkIr
> for TestDatabase
{
13 fn fn_def_variance(&self, _fn_def_id
: FnDefId
<ChalkIr
>) -> Variances
<ChalkIr
> {
14 Variances
::from_iter(&ChalkIr
, [Variance
::Invariant
; 20].iter().copied())
17 fn adt_variance(&self, _adt_id
: AdtId
<ChalkIr
>) -> Variances
<ChalkIr
> {
18 Variances
::from_iter(&ChalkIr
, [Variance
::Invariant
; 20].iter().copied())
24 // exists(A -> forall(X -> A = X)) ---> error
25 let interner
= &ChalkIr
;
26 let mut table
: InferenceTable
<ChalkIr
> = InferenceTable
::new();
27 let environment0
= Environment
::new(interner
);
28 let a
= table
.new_variable(U0
).to_ty(interner
);
43 // exists(A -> A = foo A) ---> error
44 let interner
= &ChalkIr
;
45 let mut table
: InferenceTable
<ChalkIr
> = InferenceTable
::new();
46 let environment0
= Environment
::new(interner
);
47 let a
= table
.new_variable(U0
).to_ty(interner
);
55 &ty
!(apply (item
0) (expr a
)),
59 // exists(A -> A = for<'a> A)
67 &ty
!(function
1 (infer
0)),
74 // exists(A -> A = foo B, A = B) ---> error
75 let interner
= &ChalkIr
;
76 let mut table
: InferenceTable
<ChalkIr
> = InferenceTable
::new();
77 let environment0
= Environment
::new(interner
);
78 let a
= table
.new_variable(U0
).to_ty(interner
);
79 let b
= table
.new_variable(U0
).to_ty(interner
);
87 &ty
!(apply (item
0) (expr b
)),
103 fn universe_error_indirect_1() {
104 // exists(A -> forall(X -> exists(B -> B = X, A = B))) ---> error
105 let interner
= &ChalkIr
;
106 let mut table
: InferenceTable
<ChalkIr
> = InferenceTable
::new();
107 let environment0
= Environment
::new(interner
);
108 let a
= table
.new_variable(U0
).to_ty(interner
);
109 let b
= table
.new_variable(U1
).to_ty(interner
);
133 fn universe_error_indirect_2() {
134 // exists(A -> forall(X -> exists(B -> B = A, B = X))) ---> error
135 let interner
= &ChalkIr
;
136 let mut table
: InferenceTable
<ChalkIr
> = InferenceTable
::new();
137 let environment0
= Environment
::new(interner
);
138 let a
= table
.new_variable(U0
).to_ty(interner
);
139 let b
= table
.new_variable(U1
).to_ty(interner
);
163 fn universe_promote() {
164 // exists(A -> forall(X -> exists(B -> A = foo(B), A = foo(i32)))) ---> OK
165 let interner
= &ChalkIr
;
166 let mut table
: InferenceTable
<ChalkIr
> = InferenceTable
::new();
167 let environment0
= Environment
::new(interner
);
168 let a
= table
.new_variable(U0
).to_ty(interner
);
169 let b
= table
.new_variable(U1
).to_ty(interner
);
177 &ty
!(apply (item
0) (expr b
)),
187 &ty
!(apply (item
0) (apply (item
1))),
193 fn universe_promote_bad() {
194 // exists(A -> forall(X -> exists(B -> A = foo(B), B = X))) ---> error
195 let interner
= &ChalkIr
;
196 let mut table
: InferenceTable
<ChalkIr
> = InferenceTable
::new();
197 let environment0
= Environment
::new(interner
);
198 let a
= table
.new_variable(U0
).to_ty(interner
);
199 let b
= table
.new_variable(U1
).to_ty(interner
);
207 &ty
!(apply (item
0) (expr b
)),
224 // exists(A -> A = Item0<<A as Item1>::foo>)
225 // ^^^^^^^^^^^^ Can A repeat here? For now,
226 // we say no, but it's an interesting question.
227 let interner
= &ChalkIr
;
228 let mut table
: InferenceTable
<ChalkIr
> = InferenceTable
::new();
229 let environment0
= Environment
::new(interner
);
230 let a
= table
.new_variable(U0
).to_ty(interner
);
232 // expect an error ("cycle during unification")
240 &ty
!(apply (item
0) (projection (item
1) (expr a
))),
245 const U0
: UniverseIndex
= UniverseIndex { counter: 0 }
;
246 const U1
: UniverseIndex
= UniverseIndex { counter: 1 }
;
247 const U2
: UniverseIndex
= UniverseIndex { counter: 2 }
;
249 fn make_table() -> InferenceTable
<ChalkIr
> {
250 let mut table
: InferenceTable
<ChalkIr
> = InferenceTable
::new();
251 let _
= table
.new_universe(); // U1
252 let _
= table
.new_universe(); // U2
257 fn quantify_simple() {
258 let interner
= &ChalkIr
;
259 let mut table
= make_table();
260 let _
= table
.new_variable(U0
);
261 let _
= table
.new_variable(U1
);
262 let _
= table
.new_variable(U2
);
266 .canonicalize(interner
, ty
!(apply (item
0) (infer
2) (infer
1) (infer
0)))
269 value
: ty
!(apply (item
0) (bound
0) (bound
1) (bound
2)),
270 binders
: CanonicalVarKinds
::from_iter(
273 CanonicalVarKind
::new(VariableKind
::Ty(TyVariableKind
::General
), U2
),
274 CanonicalVarKind
::new(VariableKind
::Ty(TyVariableKind
::General
), U1
),
275 CanonicalVarKind
::new(VariableKind
::Ty(TyVariableKind
::General
), U0
),
283 fn quantify_bound() {
284 let interner
= &ChalkIr
;
285 let mut table
= make_table();
286 let environment0
= Environment
::new(interner
);
288 let v0
= table
.new_variable(U0
).to_ty(interner
);
289 let v1
= table
.new_variable(U1
).to_ty(interner
);
290 let v2a
= table
.new_variable(U2
).to_ty(interner
);
291 let v2b
= table
.new_variable(U2
).to_ty(interner
);
300 &ty
!(apply (item
1) (expr v1
) (expr v0
)),
308 ty
!(apply (item
0) (expr v2b
) (expr v2a
) (expr v1
) (expr v0
))
312 value
: ty
!(apply (item
0) (apply (item
1) (bound
0) (bound
1)) (bound
2) (bound
0) (bound
1)),
313 binders
: CanonicalVarKinds
::from_iter(
316 CanonicalVarKind
::new(VariableKind
::Ty(TyVariableKind
::General
), U1
),
317 CanonicalVarKind
::new(VariableKind
::Ty(TyVariableKind
::General
), U0
),
318 CanonicalVarKind
::new(VariableKind
::Ty(TyVariableKind
::General
), U2
),
326 fn quantify_ty_under_binder() {
327 let interner
= &ChalkIr
;
328 let mut table
= make_table();
329 let v0
= table
.new_variable(U0
);
330 let v1
= table
.new_variable(U0
);
331 let _r2
= table
.new_variable(U0
);
334 let environment0
= Environment
::new(interner
);
346 // Here: the `function` introduces 3 binders, so in the result,
347 // `(bound 3)` references the first canonicalized inference
348 // variable. -- note that `infer 0` and `infer 1` have been
349 // unified above, as well.
354 ty
!(function
3 (apply (item
0) (bound
1) (infer
0) (infer
1) (lifetime (infer
2))))
358 value
: ty
!(function
3 (apply (item
0) (bound
1) (bound
1 0) (bound
1 0) (lifetime (bound
1 1)))),
359 binders
: CanonicalVarKinds
::from_iter(
362 CanonicalVarKind
::new(VariableKind
::Ty(TyVariableKind
::General
), U0
),
363 CanonicalVarKind
::new(VariableKind
::Lifetime
, U0
)
371 fn lifetime_constraint_indirect() {
372 let interner
= &ChalkIr
;
373 let mut table
: InferenceTable
<ChalkIr
> = InferenceTable
::new();
374 let _
= table
.new_universe(); // U1
376 let _t_0
= table
.new_variable(U0
);
377 let _l_1
= table
.new_variable(U1
);
379 let environment0
= Environment
::new(interner
);
381 // Here, we unify '?1 (the lifetime variable in universe 1) with
383 let t_a
= ty
!(apply (item
0) (lifetime (placeholder
1)));
384 let t_b
= ty
!(apply (item
0) (lifetime (infer
1)));
385 let RelationResult { goals }
= table
395 assert
!(goals
.is_empty());
397 // Here, we try to unify `?0` (the type variable in universe 0)
398 // with something that involves `'?1`. Since `'?1` has been
399 // unified with `'!1`, and `'!1` is not visible from universe 0,
400 // we will replace `'!1` with a new variable `'?2` and introduce a
401 // (likely unsatisfiable) constraint relating them.
402 let t_c
= ty
!(infer
0);
403 let RelationResult { goals }
= table
413 assert_eq
!(goals
.len(), 2);
415 format
!("{:?}", goals
[0]),
416 "InEnvironment { environment: Env([]), goal: \'?2: \'!1_0 }",
419 format
!("{:?}", goals
[1]),
420 "InEnvironment { environment: Env([]), goal: \'!1_0: \'?2 }",