Unify couldContainTypeVariables and the similar check done during instantiation (#30969)

* Stop symbol based filtering in couldContainTypeVariables

* Unify couldContainTypeVariables and the similar check done during instantiation
This commit is contained in:
Wesley Wigham
2019-04-19 16:01:53 -07:00
committed by GitHub
parent 1a4c15fb11
commit 40a2eb2b4b
5 changed files with 297 additions and 2 deletions

View File

@@ -11256,7 +11256,7 @@ namespace ts {
// If the anonymous type originates in a declaration of a function, method, class, or
// interface, in an object type literal, or in an object literal expression, we may need
// to instantiate the type because it might reference a type parameter.
return type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ?
return couldContainTypeVariables(type) ?
getAnonymousTypeInstantiation(<AnonymousType>type, mapper) : type;
}
if (objectFlags & ObjectFlags.Mapped) {
@@ -14557,7 +14557,7 @@ namespace ts {
const objectFlags = getObjectFlags(type);
return !!(type.flags & TypeFlags.Instantiable ||
objectFlags & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeVariables) ||
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ||
objectFlags & ObjectFlags.Mapped ||
type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeVariables(<UnionOrIntersectionType>type));
}

View File

@@ -0,0 +1,54 @@
//// [nearbyIdenticalGenericLambdasAssignable.ts]
declare const fA: <T>() => { v: T };
const fB = <T>() => {
return { v: '' as any as T };
};
const fC = <T>() => {
return {} as any as { v: T };
};
// Hover display is identical on all of these
type TA = typeof fA;
type TB = typeof fB;
type TC = typeof fC;
type TL = <T>() => { v: T };
declare function accA(x: TA): void;
declare function accB(x: TB): void;
declare function accC(x: TC): void;
declare function accL(x: TL): void;
// These should all be OK, every type is identical
accA(fA); accA(fB); accA(fC);
// ~~ previously an error
accB(fA); accB(fB); accB(fC);
// OK
accC(fA); accC(fB); accC(fC);
// ~~ previously an error
accL(fA); accL(fB); accL(fC);
// ~~ previously an error
//// [nearbyIdenticalGenericLambdasAssignable.js]
var fB = function () {
return { v: '' };
};
var fC = function () {
return {};
};
// These should all be OK, every type is identical
accA(fA);
accA(fB);
accA(fC);
// ~~ previously an error
accB(fA);
accB(fB);
accB(fC);
// OK
accC(fA);
accC(fB);
accC(fC);
// ~~ previously an error
accL(fA);
accL(fB);
accL(fC);
// ~~ previously an error

View File

@@ -0,0 +1,102 @@
=== tests/cases/compiler/nearbyIdenticalGenericLambdasAssignable.ts ===
declare const fA: <T>() => { v: T };
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 19))
>v : Symbol(v, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 28))
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 19))
const fB = <T>() => {
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 12))
return { v: '' as any as T };
>v : Symbol(v, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 2, 12))
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 12))
};
const fC = <T>() => {
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 12))
return {} as any as { v: T };
>v : Symbol(v, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 5, 25))
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 12))
};
// Hover display is identical on all of these
type TA = typeof fA;
>TA : Symbol(TA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 6, 2))
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
type TB = typeof fB;
>TB : Symbol(TB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 9, 20))
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
type TC = typeof fC;
>TC : Symbol(TC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 10, 20))
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
type TL = <T>() => { v: T };
>TL : Symbol(TL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 11, 20))
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 11))
>v : Symbol(v, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 20))
>T : Symbol(T, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 11))
declare function accA(x: TA): void;
>accA : Symbol(accA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 28))
>x : Symbol(x, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 14, 22))
>TA : Symbol(TA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 6, 2))
declare function accB(x: TB): void;
>accB : Symbol(accB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 14, 35))
>x : Symbol(x, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 15, 22))
>TB : Symbol(TB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 9, 20))
declare function accC(x: TC): void;
>accC : Symbol(accC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 15, 35))
>x : Symbol(x, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 16, 22))
>TC : Symbol(TC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 10, 20))
declare function accL(x: TL): void;
>accL : Symbol(accL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 16, 35))
>x : Symbol(x, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 17, 22))
>TL : Symbol(TL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 11, 20))
// These should all be OK, every type is identical
accA(fA); accA(fB); accA(fC);
>accA : Symbol(accA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 28))
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
>accA : Symbol(accA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 28))
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
>accA : Symbol(accA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 12, 28))
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
// ~~ previously an error
accB(fA); accB(fB); accB(fC);
>accB : Symbol(accB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 14, 35))
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
>accB : Symbol(accB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 14, 35))
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
>accB : Symbol(accB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 14, 35))
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
// OK
accC(fA); accC(fB); accC(fC);
>accC : Symbol(accC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 15, 35))
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
>accC : Symbol(accC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 15, 35))
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
>accC : Symbol(accC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 15, 35))
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
// ~~ previously an error
accL(fA); accL(fB); accL(fC);
>accL : Symbol(accL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 16, 35))
>fA : Symbol(fA, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 0, 13))
>accL : Symbol(accL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 16, 35))
>fB : Symbol(fB, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 1, 5))
>accL : Symbol(accL, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 16, 35))
>fC : Symbol(fC, Decl(nearbyIdenticalGenericLambdasAssignable.ts, 4, 5))
// ~~ previously an error

View File

@@ -0,0 +1,111 @@
=== tests/cases/compiler/nearbyIdenticalGenericLambdasAssignable.ts ===
declare const fA: <T>() => { v: T };
>fA : <T>() => { v: T; }
>v : T
const fB = <T>() => {
>fB : <T>() => { v: T; }
><T>() => { return { v: '' as any as T };} : <T>() => { v: T; }
return { v: '' as any as T };
>{ v: '' as any as T } : { v: T; }
>v : T
>'' as any as T : T
>'' as any : any
>'' : ""
};
const fC = <T>() => {
>fC : <T>() => { v: T; }
><T>() => { return {} as any as { v: T };} : <T>() => { v: T; }
return {} as any as { v: T };
>{} as any as { v: T } : { v: T; }
>{} as any : any
>{} : {}
>v : T
};
// Hover display is identical on all of these
type TA = typeof fA;
>TA : <T>() => { v: T; }
>fA : <T>() => { v: T; }
type TB = typeof fB;
>TB : <T>() => { v: T; }
>fB : <T>() => { v: T; }
type TC = typeof fC;
>TC : <T>() => { v: T; }
>fC : <T>() => { v: T; }
type TL = <T>() => { v: T };
>TL : TL
>v : T
declare function accA(x: TA): void;
>accA : (x: <T>() => { v: T; }) => void
>x : <T>() => { v: T; }
declare function accB(x: TB): void;
>accB : (x: <T>() => { v: T; }) => void
>x : <T>() => { v: T; }
declare function accC(x: TC): void;
>accC : (x: <T>() => { v: T; }) => void
>x : <T>() => { v: T; }
declare function accL(x: TL): void;
>accL : (x: TL) => void
>x : TL
// These should all be OK, every type is identical
accA(fA); accA(fB); accA(fC);
>accA(fA) : void
>accA : (x: <T>() => { v: T; }) => void
>fA : <T>() => { v: T; }
>accA(fB) : void
>accA : (x: <T>() => { v: T; }) => void
>fB : <T>() => { v: T; }
>accA(fC) : void
>accA : (x: <T>() => { v: T; }) => void
>fC : <T>() => { v: T; }
// ~~ previously an error
accB(fA); accB(fB); accB(fC);
>accB(fA) : void
>accB : (x: <T>() => { v: T; }) => void
>fA : <T>() => { v: T; }
>accB(fB) : void
>accB : (x: <T>() => { v: T; }) => void
>fB : <T>() => { v: T; }
>accB(fC) : void
>accB : (x: <T>() => { v: T; }) => void
>fC : <T>() => { v: T; }
// OK
accC(fA); accC(fB); accC(fC);
>accC(fA) : void
>accC : (x: <T>() => { v: T; }) => void
>fA : <T>() => { v: T; }
>accC(fB) : void
>accC : (x: <T>() => { v: T; }) => void
>fB : <T>() => { v: T; }
>accC(fC) : void
>accC : (x: <T>() => { v: T; }) => void
>fC : <T>() => { v: T; }
// ~~ previously an error
accL(fA); accL(fB); accL(fC);
>accL(fA) : void
>accL : (x: TL) => void
>fA : <T>() => { v: T; }
>accL(fB) : void
>accL : (x: TL) => void
>fB : <T>() => { v: T; }
>accL(fC) : void
>accL : (x: TL) => void
>fC : <T>() => { v: T; }
// ~~ previously an error

View File

@@ -0,0 +1,28 @@
declare const fA: <T>() => { v: T };
const fB = <T>() => {
return { v: '' as any as T };
};
const fC = <T>() => {
return {} as any as { v: T };
};
// Hover display is identical on all of these
type TA = typeof fA;
type TB = typeof fB;
type TC = typeof fC;
type TL = <T>() => { v: T };
declare function accA(x: TA): void;
declare function accB(x: TB): void;
declare function accC(x: TC): void;
declare function accL(x: TL): void;
// These should all be OK, every type is identical
accA(fA); accA(fB); accA(fC);
// ~~ previously an error
accB(fA); accB(fB); accB(fC);
// OK
accC(fA); accC(fB); accC(fC);
// ~~ previously an error
accL(fA); accL(fB); accL(fC);
// ~~ previously an error