From 99ba94e5776c88d37c9662efab2a57eaeb042096 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 13 May 2015 15:26:25 -0700 Subject: [PATCH 1/5] Add circularity check to getReducedTypeOfUnionType --- src/compiler/checker.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8536f24a7e2c5..e2ba28c6d2823 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -88,6 +88,7 @@ module ts { let undefinedType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsUndefinedOrNull, "undefined"); let nullType = createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsUndefinedOrNull, "null"); let unknownType = createIntrinsicType(TypeFlags.Any, "unknown"); + let resolvingType = createIntrinsicType(TypeFlags.Any, "__resolving__"); let emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); @@ -3629,9 +3630,17 @@ module ts { } function getReducedTypeOfUnionType(type: UnionType): Type { - // If union type was created without subtype reduction, perform the deferred reduction now + // If union type was created without subtype reduction, perform the deferred reduction now. If a circularity + // is detected, simply use the type itself. if (!type.reducedType) { - type.reducedType = getUnionType(type.types, /*noSubtypeReduction*/ false); + type.reducedType = resolvingType; + let reducedType = getUnionType(type.types, /*noSubtypeReduction*/ false); + if (type.reducedType === resolvingType) { + type.reducedType = reducedType; + } + } + else if (type.reducedType === resolvingType) { + type.reducedType = type; } return type.reducedType; } From fdc44b246a2ed4a307e6f40c098ebf75d0bcce05 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 13 May 2015 15:27:40 -0700 Subject: [PATCH 2/5] Adding regression tests --- ...unionTypeWithRecursiveSubtypeReduction1.js | 44 +++++++++++++++++ ...TypeWithRecursiveSubtypeReduction1.symbols | 45 +++++++++++++++++ ...onTypeWithRecursiveSubtypeReduction1.types | 45 +++++++++++++++++ ...eWithRecursiveSubtypeReduction2.errors.txt | 46 ++++++++++++++++++ ...unionTypeWithRecursiveSubtypeReduction2.js | 48 +++++++++++++++++++ ...eWithRecursiveSubtypeReduction3.errors.txt | 14 ++++++ ...unionTypeWithRecursiveSubtypeReduction3.js | 12 +++++ ...unionTypeWithRecursiveSubtypeReduction1.ts | 18 +++++++ ...unionTypeWithRecursiveSubtypeReduction2.ts | 20 ++++++++ ...unionTypeWithRecursiveSubtypeReduction3.ts | 5 ++ 10 files changed, 297 insertions(+) create mode 100644 tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.js create mode 100644 tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.symbols create mode 100644 tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.types create mode 100644 tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.errors.txt create mode 100644 tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.js create mode 100644 tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction3.errors.txt create mode 100644 tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction3.js create mode 100644 tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction1.ts create mode 100644 tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts create mode 100644 tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction3.ts diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.js b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.js new file mode 100644 index 0000000000000..f8a5cd96b4858 --- /dev/null +++ b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.js @@ -0,0 +1,44 @@ +//// [unionTypeWithRecursiveSubtypeReduction1.ts] +class Module { + public members: Class[]; +} + +class Namespace { + public members: (Class | Property)[]; +} + +class Class { + public parent: Namespace; +} + +class Property { + public parent: Module | Class; +} + +var t: Class | Property; +t.parent; + + +//// [unionTypeWithRecursiveSubtypeReduction1.js] +var Module = (function () { + function Module() { + } + return Module; +})(); +var Namespace = (function () { + function Namespace() { + } + return Namespace; +})(); +var Class = (function () { + function Class() { + } + return Class; +})(); +var Property = (function () { + function Property() { + } + return Property; +})(); +var t; +t.parent; diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.symbols b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.symbols new file mode 100644 index 0000000000000..24ba3b8a8cda4 --- /dev/null +++ b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.symbols @@ -0,0 +1,45 @@ +=== tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction1.ts === +class Module { +>Module : Symbol(Module, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 0, 0)) + + public members: Class[]; +>members : Symbol(members, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 0, 14)) +>Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 6, 1)) +} + +class Namespace { +>Namespace : Symbol(Namespace, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 2, 1)) + + public members: (Class | Property)[]; +>members : Symbol(members, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 4, 17)) +>Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 6, 1)) +>Property : Symbol(Property, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 10, 1)) +} + +class Class { +>Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 6, 1)) + + public parent: Namespace; +>parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 8, 13)) +>Namespace : Symbol(Namespace, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 2, 1)) +} + +class Property { +>Property : Symbol(Property, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 10, 1)) + + public parent: Module | Class; +>parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 12, 16)) +>Module : Symbol(Module, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 0, 0)) +>Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 6, 1)) +} + +var t: Class | Property; +>t : Symbol(t, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 16, 3)) +>Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 6, 1)) +>Property : Symbol(Property, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 10, 1)) + +t.parent; +>t.parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 8, 13), Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 12, 16)) +>t : Symbol(t, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 16, 3)) +>parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 8, 13), Decl(unionTypeWithRecursiveSubtypeReduction1.ts, 12, 16)) + diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.types b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.types new file mode 100644 index 0000000000000..c6fa610e68ae7 --- /dev/null +++ b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction1.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction1.ts === +class Module { +>Module : Module + + public members: Class[]; +>members : Class[] +>Class : Class +} + +class Namespace { +>Namespace : Namespace + + public members: (Class | Property)[]; +>members : (Class | Property)[] +>Class : Class +>Property : Property +} + +class Class { +>Class : Class + + public parent: Namespace; +>parent : Namespace +>Namespace : Namespace +} + +class Property { +>Property : Property + + public parent: Module | Class; +>parent : Module | Class +>Module : Module +>Class : Class +} + +var t: Class | Property; +>t : Class | Property +>Class : Class +>Property : Property + +t.parent; +>t.parent : Class | Namespace +>t : Class | Property +>parent : Class | Namespace + diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.errors.txt b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.errors.txt new file mode 100644 index 0000000000000..d481b88810caf --- /dev/null +++ b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.errors.txt @@ -0,0 +1,46 @@ +tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts(19,1): error TS2322: Type 'Property' is not assignable to type 'Class'. + Types of property 'parent' are incompatible. + Type 'Module | Class' is not assignable to type 'Namespace'. + Type 'Class' is not assignable to type 'Namespace'. + Property 'members' is missing in type 'Class'. +tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts(20,1): error TS2322: Type 'Class' is not assignable to type 'Property'. + Types of property 'parent' are incompatible. + Type 'Namespace' is not assignable to type 'Module | Class'. + Type 'Namespace' is not assignable to type 'Class'. + Property 'parent' is missing in type 'Namespace'. + + +==== tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts (2 errors) ==== + class Module { + public members: Class[]; + } + + class Namespace { + public members: (Class | Property)[]; + } + + class Class { + public parent: Namespace; + } + + class Property { + public parent: Module | Class; + } + + var c: Class; + var p: Property; + c = p; + ~ +!!! error TS2322: Type 'Property' is not assignable to type 'Class'. +!!! error TS2322: Types of property 'parent' are incompatible. +!!! error TS2322: Type 'Module | Class' is not assignable to type 'Namespace'. +!!! error TS2322: Type 'Class' is not assignable to type 'Namespace'. +!!! error TS2322: Property 'members' is missing in type 'Class'. + p = c; + ~ +!!! error TS2322: Type 'Class' is not assignable to type 'Property'. +!!! error TS2322: Types of property 'parent' are incompatible. +!!! error TS2322: Type 'Namespace' is not assignable to type 'Module | Class'. +!!! error TS2322: Type 'Namespace' is not assignable to type 'Class'. +!!! error TS2322: Property 'parent' is missing in type 'Namespace'. + \ No newline at end of file diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.js b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.js new file mode 100644 index 0000000000000..69411b1ffcb21 --- /dev/null +++ b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.js @@ -0,0 +1,48 @@ +//// [unionTypeWithRecursiveSubtypeReduction2.ts] +class Module { + public members: Class[]; +} + +class Namespace { + public members: (Class | Property)[]; +} + +class Class { + public parent: Namespace; +} + +class Property { + public parent: Module | Class; +} + +var c: Class; +var p: Property; +c = p; +p = c; + + +//// [unionTypeWithRecursiveSubtypeReduction2.js] +var Module = (function () { + function Module() { + } + return Module; +})(); +var Namespace = (function () { + function Namespace() { + } + return Namespace; +})(); +var Class = (function () { + function Class() { + } + return Class; +})(); +var Property = (function () { + function Property() { + } + return Property; +})(); +var c; +var p; +c = p; +p = c; diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction3.errors.txt b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction3.errors.txt new file mode 100644 index 0000000000000..279119e679acf --- /dev/null +++ b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction3.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction3.ts(5,5): error TS2322: Type '{ prop: number; } | { prop: { prop: number; } | any; }' is not assignable to type 'string'. + Type '{ prop: number; }' is not assignable to type 'string'. + + +==== tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction3.ts (1 errors) ==== + var a27: { prop: number } | { prop: T27 }; + type T27 = typeof a27; + + var b: T27; + var s: string = b; + ~ +!!! error TS2322: Type '{ prop: number; } | { prop: { prop: number; } | any; }' is not assignable to type 'string'. +!!! error TS2322: Type '{ prop: number; }' is not assignable to type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction3.js b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction3.js new file mode 100644 index 0000000000000..7c33601505909 --- /dev/null +++ b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction3.js @@ -0,0 +1,12 @@ +//// [unionTypeWithRecursiveSubtypeReduction3.ts] +var a27: { prop: number } | { prop: T27 }; +type T27 = typeof a27; + +var b: T27; +var s: string = b; + + +//// [unionTypeWithRecursiveSubtypeReduction3.js] +var a27; +var b; +var s = b; diff --git a/tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction1.ts b/tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction1.ts new file mode 100644 index 0000000000000..acdb91c99352b --- /dev/null +++ b/tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction1.ts @@ -0,0 +1,18 @@ +class Module { + public members: Class[]; +} + +class Namespace { + public members: (Class | Property)[]; +} + +class Class { + public parent: Namespace; +} + +class Property { + public parent: Module | Class; +} + +var t: Class | Property; +t.parent; diff --git a/tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts b/tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts new file mode 100644 index 0000000000000..cddcf4d45664d --- /dev/null +++ b/tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts @@ -0,0 +1,20 @@ +class Module { + public members: Class[]; +} + +class Namespace { + public members: (Class | Property)[]; +} + +class Class { + public parent: Namespace; +} + +class Property { + public parent: Module | Class; +} + +var c: Class; +var p: Property; +c = p; +p = c; diff --git a/tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction3.ts b/tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction3.ts new file mode 100644 index 0000000000000..4bac9ca1b9c83 --- /dev/null +++ b/tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction3.ts @@ -0,0 +1,5 @@ +var a27: { prop: number } | { prop: T27 }; +type T27 = typeof a27; + +var b: T27; +var s: string = b; From ec18bd081686e6db9e211099ef4e76adb67b970d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 13 May 2015 16:49:51 -0700 Subject: [PATCH 3/5] Removing stack from removeSubtypes method --- src/compiler/checker.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 11586e4944eb7..e2ba28c6d2823 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3567,19 +3567,7 @@ module ts { return false; } - // Since removeSubtypes checks the subtype relation, and the subtype relation on a union - // may attempt to reduce a union, it is possible that removeSubtypes could be called - // recursively on the same set of types. The removeSubtypesStack is used to track which - // sets of types are currently undergoing subtype reduction. - let removeSubtypesStack: string[] = []; function removeSubtypes(types: Type[]) { - let typeListId = getTypeListId(types); - if (removeSubtypesStack.lastIndexOf(typeListId) >= 0) { - return; - } - - removeSubtypesStack.push(typeListId); - let i = types.length; while (i > 0) { i--; @@ -3587,8 +3575,6 @@ module ts { types.splice(i, 1); } } - - removeSubtypesStack.pop(); } function containsAnyType(types: Type[]) { From 9befdf68f58e955ec753f833c203054e039891a1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 13 May 2015 16:55:49 -0700 Subject: [PATCH 4/5] Accepting new baselines --- .../unionTypeWithRecursiveSubtypeReduction.js | 43 ------------------ ...nTypeWithRecursiveSubtypeReduction.symbols | 45 ------------------- ...ionTypeWithRecursiveSubtypeReduction.types | 45 ------------------- ...eWithRecursiveSubtypeReduction2.errors.txt | 6 +-- ...unionTypeWithRecursiveSubtypeReduction2.js | 4 -- 5 files changed, 1 insertion(+), 142 deletions(-) delete mode 100644 tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.js delete mode 100644 tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.symbols delete mode 100644 tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.types diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.js b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.js deleted file mode 100644 index 9442d733aa475..0000000000000 --- a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.js +++ /dev/null @@ -1,43 +0,0 @@ -//// [unionTypeWithRecursiveSubtypeReduction.ts] -class Module { - public members: Class[]; -} - -class Namespace { - public members: (Class | Property)[]; -} - -class Class { - public parent: Namespace; -} - -class Property { - public parent: Module | Class; -} - -var t: Class | Property; -t.parent; - -//// [unionTypeWithRecursiveSubtypeReduction.js] -var Module = (function () { - function Module() { - } - return Module; -})(); -var Namespace = (function () { - function Namespace() { - } - return Namespace; -})(); -var Class = (function () { - function Class() { - } - return Class; -})(); -var Property = (function () { - function Property() { - } - return Property; -})(); -var t; -t.parent; diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.symbols b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.symbols deleted file mode 100644 index 93351990f6c27..0000000000000 --- a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.symbols +++ /dev/null @@ -1,45 +0,0 @@ -=== tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction.ts === -class Module { ->Module : Symbol(Module, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 0, 0)) - - public members: Class[]; ->members : Symbol(members, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 0, 14)) ->Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 6, 1)) -} - -class Namespace { ->Namespace : Symbol(Namespace, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 2, 1)) - - public members: (Class | Property)[]; ->members : Symbol(members, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 4, 17)) ->Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 6, 1)) ->Property : Symbol(Property, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 10, 1)) -} - -class Class { ->Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 6, 1)) - - public parent: Namespace; ->parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 8, 13)) ->Namespace : Symbol(Namespace, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 2, 1)) -} - -class Property { ->Property : Symbol(Property, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 10, 1)) - - public parent: Module | Class; ->parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 12, 16)) ->Module : Symbol(Module, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 0, 0)) ->Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 6, 1)) -} - -var t: Class | Property; ->t : Symbol(t, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 16, 3)) ->Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 6, 1)) ->Property : Symbol(Property, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 10, 1)) - -t.parent; ->t.parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 8, 13), Decl(unionTypeWithRecursiveSubtypeReduction.ts, 12, 16)) ->t : Symbol(t, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 16, 3)) ->parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 8, 13), Decl(unionTypeWithRecursiveSubtypeReduction.ts, 12, 16)) - diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.types b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.types deleted file mode 100644 index cf8f41d70ccc7..0000000000000 --- a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction.types +++ /dev/null @@ -1,45 +0,0 @@ -=== tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction.ts === -class Module { ->Module : Module - - public members: Class[]; ->members : Class[] ->Class : Class -} - -class Namespace { ->Namespace : Namespace - - public members: (Class | Property)[]; ->members : (Class | Property)[] ->Class : Class ->Property : Property -} - -class Class { ->Class : Class - - public parent: Namespace; ->parent : Namespace ->Namespace : Namespace -} - -class Property { ->Property : Property - - public parent: Module | Class; ->parent : Module | Class ->Module : Module ->Class : Class -} - -var t: Class | Property; ->t : Class | Property ->Class : Class ->Property : Property - -t.parent; ->t.parent : Class | Namespace ->t : Class | Property ->parent : Class | Namespace - diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.errors.txt b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.errors.txt index 592802dbca6fa..d481b88810caf 100644 --- a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.errors.txt +++ b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.errors.txt @@ -42,9 +42,5 @@ tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts(20,1): error TS2 !!! error TS2322: Types of property 'parent' are incompatible. !!! error TS2322: Type 'Namespace' is not assignable to type 'Module | Class'. !!! error TS2322: Type 'Namespace' is not assignable to type 'Class'. -<<<<<<< HEAD !!! error TS2322: Property 'parent' is missing in type 'Namespace'. - -======= -!!! error TS2322: Property 'parent' is missing in type 'Namespace'. ->>>>>>> master + \ No newline at end of file diff --git a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.js b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.js index 19dbf50da66dc..69411b1ffcb21 100644 --- a/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.js +++ b/tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.js @@ -18,12 +18,8 @@ class Property { var c: Class; var p: Property; c = p; -<<<<<<< HEAD p = c; -======= -p = c; ->>>>>>> master //// [unionTypeWithRecursiveSubtypeReduction2.js] var Module = (function () { From 194680f179497ea40208006f887cfbbe8e77391e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 15 May 2015 10:24:24 -0700 Subject: [PATCH 5/5] Addressing CR feedback --- src/compiler/checker.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e2ba28c6d2823..369f955c06d88 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -88,7 +88,7 @@ module ts { let undefinedType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsUndefinedOrNull, "undefined"); let nullType = createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsUndefinedOrNull, "null"); let unknownType = createIntrinsicType(TypeFlags.Any, "unknown"); - let resolvingType = createIntrinsicType(TypeFlags.Any, "__resolving__"); + let circularType = createIntrinsicType(TypeFlags.Any, "__circular__"); let emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); @@ -3629,17 +3629,19 @@ module ts { return type; } + // Subtype reduction is basically an optimization we do to avoid excessively large union types, which take longer + // to process and look strange in quick info and error messages. Semantically there is no difference between the + // reduced type and the type itself. So, when we detect a circularity we simply say that the reduced type is the + // type itself. function getReducedTypeOfUnionType(type: UnionType): Type { - // If union type was created without subtype reduction, perform the deferred reduction now. If a circularity - // is detected, simply use the type itself. if (!type.reducedType) { - type.reducedType = resolvingType; + type.reducedType = circularType; let reducedType = getUnionType(type.types, /*noSubtypeReduction*/ false); - if (type.reducedType === resolvingType) { + if (type.reducedType === circularType) { type.reducedType = reducedType; } } - else if (type.reducedType === resolvingType) { + else if (type.reducedType === circularType) { type.reducedType = type; } return type.reducedType;