Skip to content

Commit 53a7560

Browse files
committed
Accept new baselines with deeper elaborations and more correct variance analysis
1 parent 98a661b commit 53a7560

9 files changed

+116
-49
lines changed

src/compiler/checker.ts

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18007,6 +18007,7 @@ namespace ts {
1800718007
if (!variances) {
1800818008
// The emptyArray singleton is used to signal a recursive invocation.
1800918009
cache.variances = emptyArray;
18010+
let encounteredMaybeResult = false;
1801018011
variances = [];
1801118012
for (const tp of typeParameters) {
1801218013
let unmeasurable = false;
@@ -18018,21 +18019,28 @@ namespace ts {
1801818019
// invariance, covariance, contravariance or bivariance.
1801918020
const typeWithSuper = createMarkerType(cache, tp, markerSuperType);
1802018021
const typeWithSub = createMarkerType(cache, tp, markerSubType);
18021-
// Note: We consider a `Maybe` result to be affirmative below; if we're already trying to figure out if A<+?> is assignable to A<-?>
18022-
// and we end up needing to check some type we're already comparing in the body of the calling comparison, we can assume it to be true
18023-
// for the scope of the remainder of the comparison. (Simply because disproving it is the point of the _other_ comparisons we're performing)
18024-
// The issue comes with invalidating the cached variance result if the root comparison turns out to be negative. _Right now_, we're simply...
18025-
// not. This will _probably_ cause some subtle bugs, however coming up with an example exposing one such bug is nontrivial.
18026-
// But! In the event such a motiviating example should come to light, the fix shouldn't be _too_ bad - here in `getVariancesWorker` we'd
18027-
// just need a `Maybe` tracking stack just like we have in `recursiveTypeRelatedTo`.
18028-
let variance = (compareTypes(typeWithSub, typeWithSuper) ? VarianceFlags.Covariant : 0) |
18029-
(compareTypes(typeWithSuper, typeWithSub) ? VarianceFlags.Contravariant : 0);
18022+
18023+
const subResult = compareTypes(typeWithSub, typeWithSuper);
18024+
const superResult = compareTypes(typeWithSuper, typeWithSub);
18025+
let variance = (subResult ? VarianceFlags.Covariant : 0) |
18026+
(superResult ? VarianceFlags.Contravariant : 0);
18027+
if (subResult === Ternary.Maybe || superResult === Ternary.Maybe) {
18028+
variance |= VarianceFlags.Unmeasurable;
18029+
encounteredMaybeResult = true;
18030+
}
1803018031
// If the instantiations appear to be related bivariantly it may be because the
1803118032
// type parameter is independent (i.e. it isn't witnessed anywhere in the generic
1803218033
// type). To determine this we compare instantiations where the type parameter is
1803318034
// replaced with marker types that are known to be unrelated.
18034-
if (variance === VarianceFlags.Bivariant && compareTypes(createMarkerType(cache, tp, markerOtherType), typeWithSuper)) {
18035-
variance = VarianceFlags.Independent;
18035+
if (variance === VarianceFlags.Bivariant) {
18036+
const otherResult = compareTypes(createMarkerType(cache, tp, markerOtherType), typeWithSuper);
18037+
if (otherResult === Ternary.Maybe) {
18038+
variance |= VarianceFlags.Unmeasurable;
18039+
encounteredMaybeResult = true;
18040+
}
18041+
if (otherResult) {
18042+
variance = VarianceFlags.Independent;
18043+
}
1803618044
}
1803718045
outofbandVarianceMarkerHandler = oldHandler;
1803818046
if (unmeasurable || unreliable) {
@@ -18045,7 +18053,12 @@ namespace ts {
1804518053
}
1804618054
variances.push(variance);
1804718055
}
18048-
cache.variances = variances;
18056+
if (!encounteredMaybeResult) {
18057+
cache.variances = variances;
18058+
}
18059+
else {
18060+
cache.variances = undefined;
18061+
}
1804918062
}
1805018063
return variances;
1805118064
}

tests/baselines/reference/errorElaboration.errors.txt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
tests/cases/compiler/errorElaboration.ts(10,18): error TS2300: Duplicate identifier 'foo'.
22
tests/cases/compiler/errorElaboration.ts(12,5): error TS2345: Argument of type '() => Container<Ref<string>>' is not assignable to parameter of type '() => Container<Ref<number>>'.
3-
Type 'Container<Ref<string>>' is not assignable to type 'Container<Ref<number>>'.
4-
Type 'Ref<string>' is not assignable to type 'Ref<number>'.
5-
Type 'string' is not assignable to type 'number'.
3+
Call signature return types 'Container<Ref<string>>' and 'Container<Ref<number>>' are incompatible.
4+
The types of 'm1.m1.m1.m2' are incompatible between these types.
5+
Type 'Ref<Ref<Ref<Ref<string>>>>' is not assignable to type 'Ref<Ref<Ref<Ref<number>>>>'.
6+
Type 'Ref<Ref<Ref<string>>>' is not assignable to type 'Ref<Ref<Ref<number>>>'.
7+
Type 'Ref<Ref<string>>' is not assignable to type 'Ref<Ref<number>>'.
8+
Type 'Ref<string>' is not assignable to type 'Ref<number>'.
9+
Type 'string' is not assignable to type 'number'.
610
tests/cases/compiler/errorElaboration.ts(17,11): error TS2322: Type '"bar"' is not assignable to type '"foo"'.
711
tests/cases/compiler/errorElaboration.ts(22,7): error TS2300: Duplicate identifier 'foo'.
812
tests/cases/compiler/errorElaboration.ts(23,15): error TS2538: Type 'any' cannot be used as an index type.
@@ -26,9 +30,13 @@ tests/cases/compiler/errorElaboration.ts(23,19): error TS2339: Property 'bar' do
2630
foo(a);
2731
~
2832
!!! error TS2345: Argument of type '() => Container<Ref<string>>' is not assignable to parameter of type '() => Container<Ref<number>>'.
29-
!!! error TS2345: Type 'Container<Ref<string>>' is not assignable to type 'Container<Ref<number>>'.
30-
!!! error TS2345: Type 'Ref<string>' is not assignable to type 'Ref<number>'.
31-
!!! error TS2345: Type 'string' is not assignable to type 'number'.
33+
!!! error TS2345: Call signature return types 'Container<Ref<string>>' and 'Container<Ref<number>>' are incompatible.
34+
!!! error TS2345: The types of 'm1.m1.m1.m2' are incompatible between these types.
35+
!!! error TS2345: Type 'Ref<Ref<Ref<Ref<string>>>>' is not assignable to type 'Ref<Ref<Ref<Ref<number>>>>'.
36+
!!! error TS2345: Type 'Ref<Ref<Ref<string>>>' is not assignable to type 'Ref<Ref<Ref<number>>>'.
37+
!!! error TS2345: Type 'Ref<Ref<string>>' is not assignable to type 'Ref<Ref<number>>'.
38+
!!! error TS2345: Type 'Ref<string>' is not assignable to type 'Ref<number>'.
39+
!!! error TS2345: Type 'string' is not assignable to type 'number'.
3240

3341
// Repro for #25498
3442

tests/baselines/reference/genericCloneReturnTypes.errors.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
tests/cases/compiler/genericCloneReturnTypes.ts(25,1): error TS2322: Type 'Bar<string>' is not assignable to type 'Bar<number>'.
2-
Type 'string' is not assignable to type 'number'.
2+
Types of property 't' are incompatible.
3+
Type 'string' is not assignable to type 'number'.
34

45

56
==== tests/cases/compiler/genericCloneReturnTypes.ts (1 errors) ====
@@ -30,4 +31,5 @@ tests/cases/compiler/genericCloneReturnTypes.ts(25,1): error TS2322: Type 'Bar<s
3031
b = b3;
3132
~
3233
!!! error TS2322: Type 'Bar<string>' is not assignable to type 'Bar<number>'.
33-
!!! error TS2322: Type 'string' is not assignable to type 'number'.
34+
!!! error TS2322: Types of property 't' are incompatible.
35+
!!! error TS2322: Type 'string' is not assignable to type 'number'.

tests/baselines/reference/objectTypeWithRecursiveWrappedProperty.errors.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedProperty.ts(13,1): error TS2322: Type 'List<string>' is not assignable to type 'List<number>'.
2-
Type 'string' is not assignable to type 'number'.
2+
Types of property 'data' are incompatible.
3+
Type 'string' is not assignable to type 'number'.
34

45

56
==== tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedProperty.ts (1 errors) ====
@@ -18,4 +19,5 @@ tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRec
1819
list1 = list3; // error
1920
~~~~~
2021
!!! error TS2322: Type 'List<string>' is not assignable to type 'List<number>'.
21-
!!! error TS2322: Type 'string' is not assignable to type 'number'.
22+
!!! error TS2322: Types of property 'data' are incompatible.
23+
!!! error TS2322: Type 'string' is not assignable to type 'number'.

tests/baselines/reference/objectTypeWithRecursiveWrappedProperty2.errors.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedProperty2.ts(13,1): error TS2322: Type 'List<string>' is not assignable to type 'List<number>'.
2-
Type 'string' is not assignable to type 'number'.
2+
Types of property 'data' are incompatible.
3+
Type 'string' is not assignable to type 'number'.
34

45

56
==== tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedProperty2.ts (1 errors) ====
@@ -18,4 +19,5 @@ tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRec
1819
list1 = list3; // error
1920
~~~~~
2021
!!! error TS2322: Type 'List<string>' is not assignable to type 'List<number>'.
21-
!!! error TS2322: Type 'string' is not assignable to type 'number'.
22+
!!! error TS2322: Types of property 'data' are incompatible.
23+
!!! error TS2322: Type 'string' is not assignable to type 'number'.

tests/baselines/reference/objectTypeWithRecursiveWrappedPropertyCheckedNominally.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRec
1515
tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedPropertyCheckedNominally.ts(42,5): error TS2322: Type 'U' is not assignable to type 'T'.
1616
'U' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'MyList<number>'.
1717
Type 'MyList<number>' is not assignable to type 'T'.
18-
'T' could be instantiated with an arbitrary type which could be unrelated to 'MyList<number>'.
18+
'MyList<number>' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'MyList<number>'.
1919

2020

2121
==== tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedPropertyCheckedNominally.ts (5 errors) ====
@@ -83,7 +83,7 @@ tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRec
8383
!!! error TS2322: Type 'U' is not assignable to type 'T'.
8484
!!! error TS2322: 'U' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'MyList<number>'.
8585
!!! error TS2322: Type 'MyList<number>' is not assignable to type 'T'.
86-
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'MyList<number>'.
86+
!!! error TS2322: 'MyList<number>' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'MyList<number>'.
8787
u = t; // was error, ok after constraint made illegal, doesn't matter
8888

8989
var a: List<number>;

tests/baselines/reference/privateNamesInGenericClasses.errors.txt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(10,3): error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private identifier.
22
tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(11,1): error TS2322: Type 'C<string>' is not assignable to type 'C<number>'.
3-
Type 'string' is not assignable to type 'number'.
3+
Types of property '#foo' are incompatible.
4+
Type 'string' is not assignable to type 'number'.
45
tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(12,1): error TS2322: Type 'C<number>' is not assignable to type 'C<string>'.
5-
Type 'number' is not assignable to type 'string'.
6+
Types of property '#foo' are incompatible.
7+
Type 'number' is not assignable to type 'string'.
68

79

810
==== tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts (3 errors) ====
@@ -21,9 +23,11 @@ tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasse
2123
a = b; // Error
2224
~
2325
!!! error TS2322: Type 'C<string>' is not assignable to type 'C<number>'.
24-
!!! error TS2322: Type 'string' is not assignable to type 'number'.
26+
!!! error TS2322: Types of property '#foo' are incompatible.
27+
!!! error TS2322: Type 'string' is not assignable to type 'number'.
2528
b = a; // Error
2629
~
2730
!!! error TS2322: Type 'C<number>' is not assignable to type 'C<string>'.
28-
!!! error TS2322: Type 'number' is not assignable to type 'string'.
31+
!!! error TS2322: Types of property '#foo' are incompatible.
32+
!!! error TS2322: Type 'number' is not assignable to type 'string'.
2933

tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(
22
tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(8,12): error TS2504: Type 'Promise<number[]>' must have a '[Symbol.asyncIterator]()' method that returns an async iterator.
33
tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(10,7): error TS2322: Type '() => AsyncGenerator<string, void, undefined>' is not assignable to type '() => AsyncIterableIterator<number>'.
44
Call signature return types 'AsyncGenerator<string, void, undefined>' and 'AsyncIterableIterator<number>' are incompatible.
5-
The types returned by 'next(...)' are incompatible between these types.
6-
Type 'Promise<IteratorResult<string, void>>' is not assignable to type 'Promise<IteratorResult<number, any>>'.
7-
Type 'IteratorResult<string, void>' is not assignable to type 'IteratorResult<number, any>'.
8-
Type 'IteratorYieldResult<string>' is not assignable to type 'IteratorResult<number, any>'.
9-
Type 'IteratorYieldResult<string>' is not assignable to type 'IteratorYieldResult<number>'.
10-
Type 'string' is not assignable to type 'number'.
5+
The types of 'next(...).then' are incompatible between these types.
6+
Type '<TResult1 = IteratorResult<string, void>, TResult2 = never>(onfulfilled?: (value: IteratorResult<string, void>) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>' is not assignable to type '<TResult1 = IteratorResult<number, any>, TResult2 = never>(onfulfilled?: (value: IteratorResult<number, any>) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>'.
7+
Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
8+
Types of parameters 'value' and 'value' are incompatible.
9+
Type 'IteratorResult<string, void>' is not assignable to type 'IteratorResult<number, any>'.
10+
Type 'IteratorYieldResult<string>' is not assignable to type 'IteratorResult<number, any>'.
11+
Type 'IteratorYieldResult<string>' is not assignable to type 'IteratorYieldResult<number>'.
12+
Type 'string' is not assignable to type 'number'.
1113
tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(13,7): error TS2322: Type '() => AsyncGenerator<string, void, undefined>' is not assignable to type '() => AsyncIterableIterator<number>'.
1214
Type 'AsyncGenerator<string, void, undefined>' is not assignable to type 'AsyncIterableIterator<number>'.
1315
tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(16,7): error TS2322: Type '() => AsyncGenerator<string, void, unknown>' is not assignable to type '() => AsyncIterableIterator<number>'.
@@ -67,12 +69,14 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(
6769
~~~~~~~~~~~~~~
6870
!!! error TS2322: Type '() => AsyncGenerator<string, void, undefined>' is not assignable to type '() => AsyncIterableIterator<number>'.
6971
!!! error TS2322: Call signature return types 'AsyncGenerator<string, void, undefined>' and 'AsyncIterableIterator<number>' are incompatible.
70-
!!! error TS2322: The types returned by 'next(...)' are incompatible between these types.
71-
!!! error TS2322: Type 'Promise<IteratorResult<string, void>>' is not assignable to type 'Promise<IteratorResult<number, any>>'.
72-
!!! error TS2322: Type 'IteratorResult<string, void>' is not assignable to type 'IteratorResult<number, any>'.
73-
!!! error TS2322: Type 'IteratorYieldResult<string>' is not assignable to type 'IteratorResult<number, any>'.
74-
!!! error TS2322: Type 'IteratorYieldResult<string>' is not assignable to type 'IteratorYieldResult<number>'.
75-
!!! error TS2322: Type 'string' is not assignable to type 'number'.
72+
!!! error TS2322: The types of 'next(...).then' are incompatible between these types.
73+
!!! error TS2322: Type '<TResult1 = IteratorResult<string, void>, TResult2 = never>(onfulfilled?: (value: IteratorResult<string, void>) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>' is not assignable to type '<TResult1 = IteratorResult<number, any>, TResult2 = never>(onfulfilled?: (value: IteratorResult<number, any>) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>'.
74+
!!! error TS2322: Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
75+
!!! error TS2322: Types of parameters 'value' and 'value' are incompatible.
76+
!!! error TS2322: Type 'IteratorResult<string, void>' is not assignable to type 'IteratorResult<number, any>'.
77+
!!! error TS2322: Type 'IteratorYieldResult<string>' is not assignable to type 'IteratorResult<number, any>'.
78+
!!! error TS2322: Type 'IteratorYieldResult<string>' is not assignable to type 'IteratorYieldResult<number>'.
79+
!!! error TS2322: Type 'string' is not assignable to type 'number'.
7680
yield "a";
7781
};
7882
const assignability2: () => AsyncIterableIterator<number> = async function * () {

0 commit comments

Comments
 (0)