From 10beac2c1cc849348421cf70b74a81b2b38e1126 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 7 Jun 2017 12:58:36 -0700 Subject: [PATCH 1/2] Delay instantiation of signature return type `getReturnTypeOfSignature` correctly handles an un-instantiated signature, but `instantiateSignature` used to eagerly instantiate the return type. This caused an infinite recursion in #16233. Now `instantiateSignature` doesn't instantiate the return type, but relies on `getReturnTypeOfSignature` to do it. --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bde5e050fb1..4df03b95d48 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8038,7 +8038,7 @@ namespace ts { const result = createSignature(signature.declaration, freshTypeParameters, signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper), instantiateList(signature.parameters, mapper, instantiateSymbol), - instantiateType(signature.resolvedReturnType, mapper), + /*resolvedReturnType*/ undefined, freshTypePredicate, signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes); result.target = signature; From c0b8c217b1da47d552f9f04c79e7c89584d8c848 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 7 Jun 2017 13:27:31 -0700 Subject: [PATCH 2/2] Test returning an infinite type in an intersection --- .../reference/returnInfiniteIntersection.js | 15 +++++++++++ .../returnInfiniteIntersection.symbols | 21 +++++++++++++++ .../returnInfiniteIntersection.types | 27 +++++++++++++++++++ .../compiler/returnInfiniteIntersection.ts | 6 +++++ 4 files changed, 69 insertions(+) create mode 100644 tests/baselines/reference/returnInfiniteIntersection.js create mode 100644 tests/baselines/reference/returnInfiniteIntersection.symbols create mode 100644 tests/baselines/reference/returnInfiniteIntersection.types create mode 100644 tests/cases/compiler/returnInfiniteIntersection.ts diff --git a/tests/baselines/reference/returnInfiniteIntersection.js b/tests/baselines/reference/returnInfiniteIntersection.js new file mode 100644 index 00000000000..db77d21f32d --- /dev/null +++ b/tests/baselines/reference/returnInfiniteIntersection.js @@ -0,0 +1,15 @@ +//// [returnInfiniteIntersection.ts] +function recursive() { + let x = (subkey: T) => recursive(); + return x as typeof x & { p }; +} + +let result = recursive()(1) + + +//// [returnInfiniteIntersection.js] +function recursive() { + var x = function (subkey) { return recursive(); }; + return x; +} +var result = recursive()(1); diff --git a/tests/baselines/reference/returnInfiniteIntersection.symbols b/tests/baselines/reference/returnInfiniteIntersection.symbols new file mode 100644 index 00000000000..125861ac78d --- /dev/null +++ b/tests/baselines/reference/returnInfiniteIntersection.symbols @@ -0,0 +1,21 @@ +=== tests/cases/compiler/returnInfiniteIntersection.ts === +function recursive() { +>recursive : Symbol(recursive, Decl(returnInfiniteIntersection.ts, 0, 0)) + + let x = (subkey: T) => recursive(); +>x : Symbol(x, Decl(returnInfiniteIntersection.ts, 1, 7)) +>T : Symbol(T, Decl(returnInfiniteIntersection.ts, 1, 13)) +>subkey : Symbol(subkey, Decl(returnInfiniteIntersection.ts, 1, 16)) +>T : Symbol(T, Decl(returnInfiniteIntersection.ts, 1, 13)) +>recursive : Symbol(recursive, Decl(returnInfiniteIntersection.ts, 0, 0)) + + return x as typeof x & { p }; +>x : Symbol(x, Decl(returnInfiniteIntersection.ts, 1, 7)) +>x : Symbol(x, Decl(returnInfiniteIntersection.ts, 1, 7)) +>p : Symbol(p, Decl(returnInfiniteIntersection.ts, 2, 28)) +} + +let result = recursive()(1) +>result : Symbol(result, Decl(returnInfiniteIntersection.ts, 5, 3)) +>recursive : Symbol(recursive, Decl(returnInfiniteIntersection.ts, 0, 0)) + diff --git a/tests/baselines/reference/returnInfiniteIntersection.types b/tests/baselines/reference/returnInfiniteIntersection.types new file mode 100644 index 00000000000..e7ca48a69d1 --- /dev/null +++ b/tests/baselines/reference/returnInfiniteIntersection.types @@ -0,0 +1,27 @@ +=== tests/cases/compiler/returnInfiniteIntersection.ts === +function recursive() { +>recursive : () => ((subkey: T) => any & { p: any; }) & { p: any; } + + let x = (subkey: T) => recursive(); +>x : (subkey: T) => any & { p: any; } +>(subkey: T) => recursive() : (subkey: T) => any & { p: any; } +>T : T +>subkey : T +>T : T +>recursive() : ((subkey: T) => any & { p: any; }) & { p: any; } +>recursive : () => ((subkey: T) => any & { p: any; }) & { p: any; } + + return x as typeof x & { p }; +>x as typeof x & { p } : ((subkey: T) => any & { p: any; }) & { p: any; } +>x : (subkey: T) => any & { p: any; } +>x : (subkey: T) => any & { p: any; } +>p : any +} + +let result = recursive()(1) +>result : ((subkey: T) => any & { p: any; }) & { p: any; } +>recursive()(1) : ((subkey: T) => any & { p: any; }) & { p: any; } +>recursive() : ((subkey: T) => any & { p: any; }) & { p: any; } +>recursive : () => ((subkey: T) => any & { p: any; }) & { p: any; } +>1 : 1 + diff --git a/tests/cases/compiler/returnInfiniteIntersection.ts b/tests/cases/compiler/returnInfiniteIntersection.ts new file mode 100644 index 00000000000..3bb0d1fcc79 --- /dev/null +++ b/tests/cases/compiler/returnInfiniteIntersection.ts @@ -0,0 +1,6 @@ +function recursive() { + let x = (subkey: T) => recursive(); + return x as typeof x & { p }; +} + +let result = recursive()(1)