Skip to content

Commit 40a2eb2

Browse files
authored
Unify couldContainTypeVariables and the similar check done during instantiation (microsoft#30969)
* Stop symbol based filtering in couldContainTypeVariables * Unify couldContainTypeVariables and the similar check done during instantiation
1 parent 1a4c15f commit 40a2eb2

File tree

5 files changed

+297
-2
lines changed

5 files changed

+297
-2
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11256,7 +11256,7 @@ namespace ts {
1125611256
// If the anonymous type originates in a declaration of a function, method, class, or
1125711257
// interface, in an object type literal, or in an object literal expression, we may need
1125811258
// to instantiate the type because it might reference a type parameter.
11259-
return type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ?
11259+
return couldContainTypeVariables(type) ?
1126011260
getAnonymousTypeInstantiation(<AnonymousType>type, mapper) : type;
1126111261
}
1126211262
if (objectFlags & ObjectFlags.Mapped) {
@@ -14557,7 +14557,7 @@ namespace ts {
1455714557
const objectFlags = getObjectFlags(type);
1455814558
return !!(type.flags & TypeFlags.Instantiable ||
1455914559
objectFlags & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeVariables) ||
14560-
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
14560+
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ||
1456114561
objectFlags & ObjectFlags.Mapped ||
1456214562
type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeVariables(<UnionOrIntersectionType>type));
1456314563
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//// [nearbyIdenticalGenericLambdasAssignable.ts]
2+
declare const fA: <T>() => { v: T };
3+
const fB = <T>() => {
4+
return { v: '' as any as T };
5+
};
6+
const fC = <T>() => {
7+
return {} as any as { v: T };
8+
};
9+
10+
// Hover display is identical on all of these
11+
type TA = typeof fA;
12+
type TB = typeof fB;
13+
type TC = typeof fC;
14+
type TL = <T>() => { v: T };
15+
16+
declare function accA(x: TA): void;
17+
declare function accB(x: TB): void;
18+
declare function accC(x: TC): void;
19+
declare function accL(x: TL): void;
20+
21+
// These should all be OK, every type is identical
22+
accA(fA); accA(fB); accA(fC);
23+
// ~~ previously an error
24+
accB(fA); accB(fB); accB(fC);
25+
// OK
26+
accC(fA); accC(fB); accC(fC);
27+
// ~~ previously an error
28+
accL(fA); accL(fB); accL(fC);
29+
// ~~ previously an error
30+
31+
//// [nearbyIdenticalGenericLambdasAssignable.js]
32+
var fB = function () {
33+
return { v: '' };
34+
};
35+
var fC = function () {
36+
return {};
37+
};
38+
// These should all be OK, every type is identical
39+
accA(fA);
40+
accA(fB);
41+
accA(fC);
42+
// ~~ previously an error
43+
accB(fA);
44+
accB(fB);
45+
accB(fC);
46+
// OK
47+
accC(fA);
48+
accC(fB);
49+
accC(fC);
50+
// ~~ previously an error
51+
accL(fA);
52+
accL(fB);
53+
accL(fC);
54+
// ~~ previously an error
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
=== tests/cases/compiler/nearbyIdenticalGenericLambdasAssignable.ts ===
2+
declare const fA: <T>() => { v: T };
3+
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
4+
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 19))
5+
>v : Symbol(v, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 28))
6+
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 19))
7+
8+
const fB = <T>() => {
9+
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
10+
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 12))
11+
12+
return { v: '' as any as T };
13+
>v : Symbol(v, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 2, 12))
14+
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 12))
15+
16+
};
17+
const fC = <T>() => {
18+
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
19+
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 12))
20+
21+
return {} as any as { v: T };
22+
>v : Symbol(v, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 5, 25))
23+
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 12))
24+
25+
};
26+
27+
// Hover display is identical on all of these
28+
type TA = typeof fA;
29+
>TA : Symbol(TA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 6, 2))
30+
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
31+
32+
type TB = typeof fB;
33+
>TB : Symbol(TB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 9, 20))
34+
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
35+
36+
type TC = typeof fC;
37+
>TC : Symbol(TC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 10, 20))
38+
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
39+
40+
type TL = <T>() => { v: T };
41+
>TL : Symbol(TL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 11, 20))
42+
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 11))
43+
>v : Symbol(v, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 20))
44+
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 11))
45+
46+
declare function accA(x: TA): void;
47+
>accA : Symbol(accA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 28))
48+
>x : Symbol(x, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 14, 22))
49+
>TA : Symbol(TA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 6, 2))
50+
51+
declare function accB(x: TB): void;
52+
>accB : Symbol(accB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 14, 35))
53+
>x : Symbol(x, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 15, 22))
54+
>TB : Symbol(TB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 9, 20))
55+
56+
declare function accC(x: TC): void;
57+
>accC : Symbol(accC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 15, 35))
58+
>x : Symbol(x, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 16, 22))
59+
>TC : Symbol(TC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 10, 20))
60+
61+
declare function accL(x: TL): void;
62+
>accL : Symbol(accL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 16, 35))
63+
>x : Symbol(x, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 17, 22))
64+
>TL : Symbol(TL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 11, 20))
65+
66+
// These should all be OK, every type is identical
67+
accA(fA); accA(fB); accA(fC);
68+
>accA : Symbol(accA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 28))
69+
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
70+
>accA : Symbol(accA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 28))
71+
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
72+
>accA : Symbol(accA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 28))
73+
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
74+
75+
// ~~ previously an error
76+
accB(fA); accB(fB); accB(fC);
77+
>accB : Symbol(accB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 14, 35))
78+
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
79+
>accB : Symbol(accB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 14, 35))
80+
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
81+
>accB : Symbol(accB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 14, 35))
82+
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
83+
84+
// OK
85+
accC(fA); accC(fB); accC(fC);
86+
>accC : Symbol(accC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 15, 35))
87+
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
88+
>accC : Symbol(accC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 15, 35))
89+
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
90+
>accC : Symbol(accC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 15, 35))
91+
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
92+
93+
// ~~ previously an error
94+
accL(fA); accL(fB); accL(fC);
95+
>accL : Symbol(accL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 16, 35))
96+
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
97+
>accL : Symbol(accL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 16, 35))
98+
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
99+
>accL : Symbol(accL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 16, 35))
100+
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
101+
102+
// ~~ previously an error
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
=== tests/cases/compiler/nearbyIdenticalGenericLambdasAssignable.ts ===
2+
declare const fA: <T>() => { v: T };
3+
>fA : <T>() => { v: T; }
4+
>v : T
5+
6+
const fB = <T>() => {
7+
>fB : <T>() => { v: T; }
8+
><T>() => { return { v: '' as any as T };} : <T>() => { v: T; }
9+
10+
return { v: '' as any as T };
11+
>{ v: '' as any as T } : { v: T; }
12+
>v : T
13+
>'' as any as T : T
14+
>'' as any : any
15+
>'' : ""
16+
17+
};
18+
const fC = <T>() => {
19+
>fC : <T>() => { v: T; }
20+
><T>() => { return {} as any as { v: T };} : <T>() => { v: T; }
21+
22+
return {} as any as { v: T };
23+
>{} as any as { v: T } : { v: T; }
24+
>{} as any : any
25+
>{} : {}
26+
>v : T
27+
28+
};
29+
30+
// Hover display is identical on all of these
31+
type TA = typeof fA;
32+
>TA : <T>() => { v: T; }
33+
>fA : <T>() => { v: T; }
34+
35+
type TB = typeof fB;
36+
>TB : <T>() => { v: T; }
37+
>fB : <T>() => { v: T; }
38+
39+
type TC = typeof fC;
40+
>TC : <T>() => { v: T; }
41+
>fC : <T>() => { v: T; }
42+
43+
type TL = <T>() => { v: T };
44+
>TL : TL
45+
>v : T
46+
47+
declare function accA(x: TA): void;
48+
>accA : (x: <T>() => { v: T; }) => void
49+
>x : <T>() => { v: T; }
50+
51+
declare function accB(x: TB): void;
52+
>accB : (x: <T>() => { v: T; }) => void
53+
>x : <T>() => { v: T; }
54+
55+
declare function accC(x: TC): void;
56+
>accC : (x: <T>() => { v: T; }) => void
57+
>x : <T>() => { v: T; }
58+
59+
declare function accL(x: TL): void;
60+
>accL : (x: TL) => void
61+
>x : TL
62+
63+
// These should all be OK, every type is identical
64+
accA(fA); accA(fB); accA(fC);
65+
>accA(fA) : void
66+
>accA : (x: <T>() => { v: T; }) => void
67+
>fA : <T>() => { v: T; }
68+
>accA(fB) : void
69+
>accA : (x: <T>() => { v: T; }) => void
70+
>fB : <T>() => { v: T; }
71+
>accA(fC) : void
72+
>accA : (x: <T>() => { v: T; }) => void
73+
>fC : <T>() => { v: T; }
74+
75+
// ~~ previously an error
76+
accB(fA); accB(fB); accB(fC);
77+
>accB(fA) : void
78+
>accB : (x: <T>() => { v: T; }) => void
79+
>fA : <T>() => { v: T; }
80+
>accB(fB) : void
81+
>accB : (x: <T>() => { v: T; }) => void
82+
>fB : <T>() => { v: T; }
83+
>accB(fC) : void
84+
>accB : (x: <T>() => { v: T; }) => void
85+
>fC : <T>() => { v: T; }
86+
87+
// OK
88+
accC(fA); accC(fB); accC(fC);
89+
>accC(fA) : void
90+
>accC : (x: <T>() => { v: T; }) => void
91+
>fA : <T>() => { v: T; }
92+
>accC(fB) : void
93+
>accC : (x: <T>() => { v: T; }) => void
94+
>fB : <T>() => { v: T; }
95+
>accC(fC) : void
96+
>accC : (x: <T>() => { v: T; }) => void
97+
>fC : <T>() => { v: T; }
98+
99+
// ~~ previously an error
100+
accL(fA); accL(fB); accL(fC);
101+
>accL(fA) : void
102+
>accL : (x: TL) => void
103+
>fA : <T>() => { v: T; }
104+
>accL(fB) : void
105+
>accL : (x: TL) => void
106+
>fB : <T>() => { v: T; }
107+
>accL(fC) : void
108+
>accL : (x: TL) => void
109+
>fC : <T>() => { v: T; }
110+
111+
// ~~ previously an error
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
declare const fA: <T>() => { v: T };
2+
const fB = <T>() => {
3+
return { v: '' as any as T };
4+
};
5+
const fC = <T>() => {
6+
return {} as any as { v: T };
7+
};
8+
9+
// Hover display is identical on all of these
10+
type TA = typeof fA;
11+
type TB = typeof fB;
12+
type TC = typeof fC;
13+
type TL = <T>() => { v: T };
14+
15+
declare function accA(x: TA): void;
16+
declare function accB(x: TB): void;
17+
declare function accC(x: TC): void;
18+
declare function accL(x: TL): void;
19+
20+
// These should all be OK, every type is identical
21+
accA(fA); accA(fB); accA(fC);
22+
// ~~ previously an error
23+
accB(fA); accB(fB); accB(fC);
24+
// OK
25+
accC(fA); accC(fB); accC(fC);
26+
// ~~ previously an error
27+
accL(fA); accL(fB); accL(fC);
28+
// ~~ previously an error

0 commit comments

Comments
 (0)