Skip to content

Commit b824cbc

Browse files
committed
Add test with notes
1 parent db0576c commit b824cbc

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
3+
Debugging notes: variance measurement for `Parent` is getting set to
4+
`VarianceFlags.Independent`, implying that its type parameter is never
5+
witnessed at all. It arrived at this conclusion by checking the assignability
6+
of `Parent` instantiated with marker types. It first checks assignability in
7+
both directions with instantiations with super/sub-related marker types, and
8+
assignability appears to return true in both directions; however, it actually
9+
is returning `Ternary.Unknown`, due to being unable to answer questions about
10+
the assignability of the types' `parent` and `child` properties without knowing
11+
their variances. After (incorrectly) concluding that `Parent` is bivariant on `A`,
12+
it checks another set of instantiations with markers that are unrelated to each
13+
other. That too comes back as `Ternary.Unknown` but is interpreted as true, so
14+
the variance gets updated to `Independent`, since instantiating `Parent` with
15+
all kinds of different markers with different assignability to each other
16+
apparently had no effect on the instantiations' assignability to each other.
17+
18+
I'm not sure if any of those comparisons ever actually looked at `a` and `b`,
19+
which should provide some non-recursive concrete variance information. I'm also
20+
not sure if `outofbandVarianceMarkerHandler` should have been called at some point,
21+
but it was not.
22+
23+
*/
24+
25+
interface Parent<A> {
26+
child: Child<A> | null;
27+
parent: Parent<A> | null;
28+
}
29+
30+
interface Child<A, B = unknown> extends Parent<A> {
31+
readonly a: A;
32+
// This field isn't necessary to the repro, but the
33+
// type parameter is, so including it
34+
readonly b: B;
35+
}
36+
37+
function fn<A>(inp: Child<A>) {
38+
// This assignability check defeats the later one
39+
const a: Child<unknown> = inp;
40+
}
41+
42+
// Allowed initialization of pu
43+
const pu: Parent<unknown> = { child: { a: 0, b: 0, child: null, parent: null }, parent: null };
44+
45+
// Should error
46+
const notString: Parent<string> = pu;

0 commit comments

Comments
 (0)