From bffcd206caab5ceccefa8179c5b8b957b0767565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Fri, 24 Jun 2022 23:26:17 +0200 Subject: [PATCH 1/2] Fixed an issue with self-referential awaited union --- src/compiler/checker.ts | 14 +++++++++++- ...ableSelfReferencingAwaitedUnion.errors.txt | 19 ++++++++++++++++ ...olvableSelfReferencingAwaitedUnion.symbols | 22 +++++++++++++++++++ ...esolvableSelfReferencingAwaitedUnion.types | 17 ++++++++++++++ ...UnresolvableSelfReferencingAwaitedUnion.ts | 11 ++++++++++ 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.errors.txt create mode 100644 tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.symbols create mode 100644 tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.types create mode 100644 tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a53c1841b6ef4..5a478c52b9e65 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36625,8 +36625,20 @@ namespace ts { // For a union, get a union of the awaited types of each constituent. if (type.flags & TypeFlags.Union) { + if (awaitedTypeStack.lastIndexOf(type.id) >= 0) { + if (errorNode) { + error(errorNode, Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method); + } + return undefined; + } + const mapper = errorNode ? (constituentType: Type) => getAwaitedTypeNoAlias(constituentType, errorNode, diagnosticMessage, arg0) : getAwaitedTypeNoAlias; - return typeAsAwaitable.awaitedTypeOfType = mapType(type, mapper); + + awaitedTypeStack.push(type.id); + const mapped = mapType(type, mapper); + awaitedTypeStack.pop(); + + return typeAsAwaitable.awaitedTypeOfType = mapped; } const thisTypeForErrorOut: { value: Type | undefined } = { value: undefined }; diff --git a/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.errors.txt b/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.errors.txt new file mode 100644 index 0000000000000..57e99000a4533 --- /dev/null +++ b/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts(9,32): error TS2322: Type 'SimpleType' is not assignable to type 'T'. + 'T' could be instantiated with an arbitrary type which could be unrelated to 'SimpleType'. + + +==== tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts (1 errors) ==== + // repro #49646 + + type EnvFunction = () => T; + + type SimpleType = string | Promise; + + declare const simple: SimpleType; + + const env: EnvFunction = () => simple; + ~~~~~~ +!!! error TS2322: Type 'SimpleType' is not assignable to type 'T'. +!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'SimpleType'. +!!! related TS6502 tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts:3:20: The expected type comes from the return type of this signature. + \ No newline at end of file diff --git a/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.symbols b/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.symbols new file mode 100644 index 0000000000000..0e1564c6cbd06 --- /dev/null +++ b/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.symbols @@ -0,0 +1,22 @@ +=== tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts === +// repro #49646 + +type EnvFunction = () => T; +>EnvFunction : Symbol(EnvFunction, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 0, 0)) +>T : Symbol(T, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 2, 20)) +>T : Symbol(T, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 2, 20)) + +type SimpleType = string | Promise; +>SimpleType : Symbol(SimpleType, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 2, 30)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) +>SimpleType : Symbol(SimpleType, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 2, 30)) + +declare const simple: SimpleType; +>simple : Symbol(simple, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 6, 13)) +>SimpleType : Symbol(SimpleType, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 2, 30)) + +const env: EnvFunction = () => simple; +>env : Symbol(env, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 8, 5)) +>EnvFunction : Symbol(EnvFunction, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 0, 0)) +>simple : Symbol(simple, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 6, 13)) + diff --git a/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.types b/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.types new file mode 100644 index 0000000000000..32881d7c93529 --- /dev/null +++ b/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts === +// repro #49646 + +type EnvFunction = () => T; +>EnvFunction : () => T + +type SimpleType = string | Promise; +>SimpleType : string | Promise + +declare const simple: SimpleType; +>simple : SimpleType + +const env: EnvFunction = () => simple; +>env : EnvFunction +>() => simple : () => SimpleType +>simple : SimpleType + diff --git a/tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts b/tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts new file mode 100644 index 0000000000000..5564ec6e17dd4 --- /dev/null +++ b/tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts @@ -0,0 +1,11 @@ +// @noEmit: true + +// repro #49646 + +type EnvFunction = () => T; + +type SimpleType = string | Promise; + +declare const simple: SimpleType; + +const env: EnvFunction = () => simple; From 30a80a99b4702b1445cde1d5ca4153b339404d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 29 Jun 2022 21:33:22 +0200 Subject: [PATCH 2/2] Add test from #49723 --- ...ableSelfReferencingAwaitedUnion.errors.txt | 19 --------- ...olvableSelfReferencingAwaitedUnion.symbols | 22 ---------- ...esolvableSelfReferencingAwaitedUnion.types | 17 -------- ...ableSelfReferencingAwaitedUnion.errors.txt | 30 ++++++++++++++ ...olvableSelfReferencingAwaitedUnion.symbols | 40 +++++++++++++++++++ ...esolvableSelfReferencingAwaitedUnion.types | 32 +++++++++++++++ ...nresolvableSelfReferencingAwaitedUnion.ts} | 8 ++++ 7 files changed, 110 insertions(+), 58 deletions(-) delete mode 100644 tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.errors.txt delete mode 100644 tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.symbols delete mode 100644 tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.types create mode 100644 tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.errors.txt create mode 100644 tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.symbols create mode 100644 tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.types rename tests/cases/compiler/{genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts => unresolvableSelfReferencingAwaitedUnion.ts} (59%) diff --git a/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.errors.txt b/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.errors.txt deleted file mode 100644 index 57e99000a4533..0000000000000 --- a/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.errors.txt +++ /dev/null @@ -1,19 +0,0 @@ -tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts(9,32): error TS2322: Type 'SimpleType' is not assignable to type 'T'. - 'T' could be instantiated with an arbitrary type which could be unrelated to 'SimpleType'. - - -==== tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts (1 errors) ==== - // repro #49646 - - type EnvFunction = () => T; - - type SimpleType = string | Promise; - - declare const simple: SimpleType; - - const env: EnvFunction = () => simple; - ~~~~~~ -!!! error TS2322: Type 'SimpleType' is not assignable to type 'T'. -!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'SimpleType'. -!!! related TS6502 tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts:3:20: The expected type comes from the return type of this signature. - \ No newline at end of file diff --git a/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.symbols b/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.symbols deleted file mode 100644 index 0e1564c6cbd06..0000000000000 --- a/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.symbols +++ /dev/null @@ -1,22 +0,0 @@ -=== tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts === -// repro #49646 - -type EnvFunction = () => T; ->EnvFunction : Symbol(EnvFunction, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 0, 0)) ->T : Symbol(T, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 2, 20)) ->T : Symbol(T, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 2, 20)) - -type SimpleType = string | Promise; ->SimpleType : Symbol(SimpleType, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 2, 30)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) ->SimpleType : Symbol(SimpleType, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 2, 30)) - -declare const simple: SimpleType; ->simple : Symbol(simple, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 6, 13)) ->SimpleType : Symbol(SimpleType, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 2, 30)) - -const env: EnvFunction = () => simple; ->env : Symbol(env, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 8, 5)) ->EnvFunction : Symbol(EnvFunction, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 0, 0)) ->simple : Symbol(simple, Decl(genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts, 6, 13)) - diff --git a/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.types b/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.types deleted file mode 100644 index 32881d7c93529..0000000000000 --- a/tests/baselines/reference/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.types +++ /dev/null @@ -1,17 +0,0 @@ -=== tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts === -// repro #49646 - -type EnvFunction = () => T; ->EnvFunction : () => T - -type SimpleType = string | Promise; ->SimpleType : string | Promise - -declare const simple: SimpleType; ->simple : SimpleType - -const env: EnvFunction = () => simple; ->env : EnvFunction ->() => simple : () => SimpleType ->simple : SimpleType - diff --git a/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.errors.txt b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.errors.txt new file mode 100644 index 0000000000000..7d7ad42c4d034 --- /dev/null +++ b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.errors.txt @@ -0,0 +1,30 @@ +tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts(9,32): error TS2322: Type 'SimpleType' is not assignable to type 'T'. + 'T' could be instantiated with an arbitrary type which could be unrelated to 'SimpleType'. +tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts(16,19): error TS1062: Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method. + + +==== tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts (2 errors) ==== + // repro #49646 + + type EnvFunction = () => T; + + type SimpleType = string | Promise; + + declare const simple: SimpleType; + + const env: EnvFunction = () => simple; + ~~~~~~ +!!! error TS2322: Type 'SimpleType' is not assignable to type 'T'. +!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'SimpleType'. +!!! related TS6502 tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts:3:20: The expected type comes from the return type of this signature. + + // repro #49723 + + type T1 = 1 | Promise | T1[]; + + export async function myFunction(param: T1) { + const awaited = await param + ~~~~~~~~~~~ +!!! error TS1062: Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method. + } + \ No newline at end of file diff --git a/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.symbols b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.symbols new file mode 100644 index 0000000000000..624a339e73229 --- /dev/null +++ b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.symbols @@ -0,0 +1,40 @@ +=== tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts === +// repro #49646 + +type EnvFunction = () => T; +>EnvFunction : Symbol(EnvFunction, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 0, 0)) +>T : Symbol(T, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 20)) +>T : Symbol(T, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 20)) + +type SimpleType = string | Promise; +>SimpleType : Symbol(SimpleType, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 30)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) +>SimpleType : Symbol(SimpleType, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 30)) + +declare const simple: SimpleType; +>simple : Symbol(simple, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 6, 13)) +>SimpleType : Symbol(SimpleType, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 30)) + +const env: EnvFunction = () => simple; +>env : Symbol(env, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 5)) +>EnvFunction : Symbol(EnvFunction, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 0, 0)) +>simple : Symbol(simple, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 6, 13)) + +// repro #49723 + +type T1 = 1 | Promise | T1[]; +>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) +>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38)) +>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38)) + +export async function myFunction(param: T1) { +>myFunction : Symbol(myFunction, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 12, 33)) +>param : Symbol(param, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 14, 33)) +>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38)) + + const awaited = await param +>awaited : Symbol(awaited, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 15, 7)) +>param : Symbol(param, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 14, 33)) +} + diff --git a/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.types b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.types new file mode 100644 index 0000000000000..521bfa461e573 --- /dev/null +++ b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts === +// repro #49646 + +type EnvFunction = () => T; +>EnvFunction : () => T + +type SimpleType = string | Promise; +>SimpleType : string | Promise + +declare const simple: SimpleType; +>simple : SimpleType + +const env: EnvFunction = () => simple; +>env : EnvFunction +>() => simple : () => SimpleType +>simple : SimpleType + +// repro #49723 + +type T1 = 1 | Promise | T1[]; +>T1 : 1 | Promise | T1[] + +export async function myFunction(param: T1) { +>myFunction : (param: T1) => Promise +>param : T1 + + const awaited = await param +>awaited : 1 | T1[] +>await param : 1 | T1[] +>param : T1 +} + diff --git a/tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts b/tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts similarity index 59% rename from tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts rename to tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts index 5564ec6e17dd4..f179114ae419e 100644 --- a/tests/cases/compiler/genericFunctionAgainstUnresolvableSelfReferencingAwaitedUnion.ts +++ b/tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts @@ -9,3 +9,11 @@ type SimpleType = string | Promise; declare const simple: SimpleType; const env: EnvFunction = () => simple; + +// repro #49723 + +type T1 = 1 | Promise | T1[]; + +export async function myFunction(param: T1) { + const awaited = await param +}