From 753f0f8d1c7c514f415a8277cb9ed9f56a5fe2f6 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Wed, 22 Jul 2015 13:58:25 -0700 Subject: [PATCH] Don't add an inference candidate if it contains the anyFunctionType --- src/compiler/checker.ts | 22 ++++++++++++---------- src/compiler/types.ts | 8 ++++++-- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c09b069bee6..e0777dc67b7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -112,6 +112,8 @@ namespace ts { emptyGenericType.instantiations = {}; let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + anyFunctionType.flags |= TypeFlags.ContainsAnyFunctionType; + let noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); let anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, false, false); @@ -3759,19 +3761,19 @@ namespace ts { // This function is used to propagate widening flags when creating new object types references and union types. // It is only necessary to do so if a constituent type might be the undefined type, the null type, or the type // of an object literal (since those types have widening related information we need to track). - function getWideningFlagsOfTypes(types: Type[]): TypeFlags { + function getContainsLiteralFlagsOfTypes(types: Type[]): TypeFlags { let result: TypeFlags = 0; for (let type of types) { result |= type.flags; } - return result & TypeFlags.RequiresWidening; + return result & TypeFlags.ContainsLiteralFlags; } function createTypeReference(target: GenericType, typeArguments: Type[]): TypeReference { let id = getTypeListId(typeArguments); let type = target.instantiations[id]; if (!type) { - let flags = TypeFlags.Reference | getWideningFlagsOfTypes(typeArguments); + let flags = TypeFlags.Reference | getContainsLiteralFlagsOfTypes(typeArguments); type = target.instantiations[id] = createObjectType(flags, target.symbol); type.target = target; type.typeArguments = typeArguments; @@ -4025,7 +4027,7 @@ namespace ts { let id = getTypeListId(elementTypes); let type = tupleTypes[id]; if (!type) { - type = tupleTypes[id] = createObjectType(TypeFlags.Tuple | getWideningFlagsOfTypes(elementTypes)); + type = tupleTypes[id] = createObjectType(TypeFlags.Tuple | getContainsLiteralFlagsOfTypes(elementTypes)); type.elementTypes = elementTypes; } return type; @@ -4174,7 +4176,7 @@ namespace ts { let id = getTypeListId(typeSet); let type = unionTypes[id]; if (!type) { - type = unionTypes[id] = createObjectType(TypeFlags.Union | getWideningFlagsOfTypes(typeSet)); + type = unionTypes[id] = createObjectType(TypeFlags.Union | getContainsLiteralFlagsOfTypes(typeSet)); type.types = typeSet; } return type; @@ -4208,7 +4210,7 @@ namespace ts { let id = getTypeListId(typeSet); let type = intersectionTypes[id]; if (!type) { - type = intersectionTypes[id] = createObjectType(TypeFlags.Intersection | getWideningFlagsOfTypes(typeSet)); + type = intersectionTypes[id] = createObjectType(TypeFlags.Intersection | getContainsLiteralFlagsOfTypes(typeSet)); type.types = typeSet; } return type; @@ -5655,11 +5657,11 @@ namespace ts { } function inferFromTypes(source: Type, target: Type) { - if (source === anyFunctionType) { - return; - } if (target.flags & TypeFlags.TypeParameter) { // If target is a type parameter, make an inference + if (source.flags & TypeFlags.ContainsAnyFunctionType) { + return; + } let typeParameters = context.typeParameters; for (let i = 0; i < typeParameters.length; i++) { if (target === typeParameters[i]) { @@ -7092,7 +7094,7 @@ namespace ts { let stringIndexType = getIndexType(IndexKind.String); let numberIndexType = getIndexType(IndexKind.Number); let result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType); - result.flags |= TypeFlags.ObjectLiteral | TypeFlags.FreshObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull); + result.flags |= TypeFlags.ObjectLiteral | TypeFlags.FreshObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsLiteralFlags); return result; function getIndexType(kind: IndexKind) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8d5596c6f64..02c45968e21 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1767,7 +1767,9 @@ namespace ts { ContainsUndefinedOrNull = 0x00200000, // Type is or contains Undefined or Null type /* @internal */ ContainsObjectLiteral = 0x00400000, // Type is or contains object literal type - ESSymbol = 0x00800000, // Type of symbol primitive introduced in ES6 + /* @internal */ + ContainsAnyFunctionType = 0x00800000, // Type is or contains object literal type + ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6 /* @internal */ Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null, @@ -1779,7 +1781,9 @@ namespace ts { UnionOrIntersection = Union | Intersection, StructuredType = ObjectType | Union | Intersection, /* @internal */ - RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral + RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral, + /* @internal */ + ContainsLiteralFlags = ContainsUndefinedOrNull | ContainsObjectLiteral | ContainsAnyFunctionType } // Properties common to all types