From 3411477aab02e034e0580655204fdd8fefa00479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Fri, 28 Feb 2025 16:34:25 +0100 Subject: [PATCH] Handle `silentNeverType` in iteration-related functions --- src/compiler/checker.ts | 7 + ...AtYieldExpressionInGenericCall1.errors.txt | 34 +++++ ...allAtYieldExpressionInGenericCall1.symbols | 93 ++++++++++++ ...cCallAtYieldExpressionInGenericCall1.types | 132 ++++++++++++++++++ ...allAtYieldExpressionInGenericCall2.symbols | 111 +++++++++++++++ ...cCallAtYieldExpressionInGenericCall2.types | 123 ++++++++++++++++ ...ericCallAtYieldExpressionInGenericCall1.ts | 32 +++++ ...ericCallAtYieldExpressionInGenericCall2.ts | 32 +++++ 8 files changed, 564 insertions(+) create mode 100644 tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.errors.txt create mode 100644 tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.symbols create mode 100644 tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.types create mode 100644 tests/baselines/reference/genericCallAtYieldExpressionInGenericCall2.symbols create mode 100644 tests/baselines/reference/genericCallAtYieldExpressionInGenericCall2.types create mode 100644 tests/cases/compiler/genericCallAtYieldExpressionInGenericCall1.ts create mode 100644 tests/cases/compiler/genericCallAtYieldExpressionInGenericCall2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5aea2c15d4f21..0a3a38d89491c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2175,6 +2175,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { }; var anyIterationTypes = createIterationTypes(anyType, anyType, anyType); + var silentNeverIterationTypes = createIterationTypes(silentNeverType, silentNeverType, silentNeverType); var asyncIterationTypesResolver: IterationTypesResolver = { iterableCacheKey: "iterationTypesOfAsyncIterable", @@ -38571,6 +38572,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function getYieldedTypeOfYieldExpression(node: YieldExpression, expressionType: Type, sentType: Type, isAsync: boolean): Type | undefined { + if (expressionType === silentNeverType) { + return silentNeverType; + } const errorNode = node.expression || node; // A `yield*` expression effectively yields everything that its operand yields const yieldedType = node.asteriskToken ? checkIteratedTypeOrElementType(isAsync ? IterationUse.AsyncYieldStar : IterationUse.YieldStar, expressionType, sentType, errorNode) : expressionType; @@ -45072,6 +45076,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * the `[Symbol.asyncIterator]()` method first, and then the `[Symbol.iterator]()` method. */ function getIterationTypesOfIterable(type: Type, use: IterationUse, errorNode: Node | undefined) { + if (type === silentNeverType) { + return silentNeverIterationTypes; + } if (isTypeAny(type)) { return anyIterationTypes; } diff --git a/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.errors.txt b/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.errors.txt new file mode 100644 index 0000000000000..2e11850567bc4 --- /dev/null +++ b/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.errors.txt @@ -0,0 +1,34 @@ +genericCallAtYieldExpressionInGenericCall1.ts(26,25): error TS2488: Type '() => T' must have a '[Symbol.iterator]()' method that returns an iterator. + + +==== genericCallAtYieldExpressionInGenericCall1.ts (1 errors) ==== + declare const inner: { + (value: A): { + (): A; + [Symbol.iterator](): { + next(...args: ReadonlyArray): IteratorResult; + }; + }; + }; + + declare function outer(body: (value: A) => Generator): void; + + outer(function* (value: T) { + const result = yield* inner(value); // ok + }); + + outer(function* (value: T) { + const x = inner(value); + const result = yield* x; // ok + }); + + declare const inner2: { + (value: A): () => A; + }; + + outer(function* (value: T) { + const result = yield* inner2(value); // error + ~~~~~~~~~~~~~ +!!! error TS2488: Type '() => T' must have a '[Symbol.iterator]()' method that returns an iterator. + }); + \ No newline at end of file diff --git a/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.symbols b/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.symbols new file mode 100644 index 0000000000000..cb6dca78b13bf --- /dev/null +++ b/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.symbols @@ -0,0 +1,93 @@ +//// [tests/cases/compiler/genericCallAtYieldExpressionInGenericCall1.ts] //// + +=== genericCallAtYieldExpressionInGenericCall1.ts === +declare const inner: { +>inner : Symbol(inner, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 0, 13)) + + (value: A): { +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 1, 3)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 1, 6)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 1, 3)) + + (): A; +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 1, 3)) + + [Symbol.iterator](): { +>[Symbol.iterator] : Symbol([Symbol.iterator], Decl(genericCallAtYieldExpressionInGenericCall1.ts, 2, 10)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + next(...args: ReadonlyArray): IteratorResult; +>next : Symbol(next, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 3, 26)) +>args : Symbol(args, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 4, 11)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --) ... and 3 more) +>IteratorResult : Symbol(IteratorResult, Decl(lib.es2015.iterable.d.ts, --, --)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 1, 3)) + + }; + }; +}; + +declare function outer(body: (value: A) => Generator): void; +>outer : Symbol(outer, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 7, 2)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 9, 23)) +>body : Symbol(body, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 9, 26)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 9, 33)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 9, 23)) +>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --)) + +outer(function* (value: T) { +>outer : Symbol(outer, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 7, 2)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 11, 17)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 11, 20)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 11, 17)) + + const result = yield* inner(value); // ok +>result : Symbol(result, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 12, 7)) +>inner : Symbol(inner, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 0, 13)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 11, 20)) + +}); + +outer(function* (value: T) { +>outer : Symbol(outer, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 7, 2)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 15, 17)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 15, 20)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 15, 17)) + + const x = inner(value); +>x : Symbol(x, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 16, 7)) +>inner : Symbol(inner, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 0, 13)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 15, 20)) + + const result = yield* x; // ok +>result : Symbol(result, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 17, 7)) +>x : Symbol(x, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 16, 7)) + +}); + +declare const inner2: { +>inner2 : Symbol(inner2, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 20, 13)) + + (value: A): () => A; +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 21, 3)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 21, 6)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 21, 3)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 21, 3)) + +}; + +outer(function* (value: T) { +>outer : Symbol(outer, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 7, 2)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 24, 17)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 24, 20)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 24, 17)) + + const result = yield* inner2(value); // error +>result : Symbol(result, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 25, 7)) +>inner2 : Symbol(inner2, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 20, 13)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 24, 20)) + +}); + diff --git a/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.types b/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.types new file mode 100644 index 0000000000000..e0b92b3ccd070 --- /dev/null +++ b/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall1.types @@ -0,0 +1,132 @@ +//// [tests/cases/compiler/genericCallAtYieldExpressionInGenericCall1.ts] //// + +=== Performance Stats === +Type Count: 1,000 +Instantiation count: 2,500 + +=== genericCallAtYieldExpressionInGenericCall1.ts === +declare const inner: { +>inner : (value: A) => { (): A; [Symbol.iterator](): { next(...args: ReadonlyArray): IteratorResult; }; } +> : ^ ^^ ^^ ^^^^^ + + (value: A): { +>value : A +> : ^ + + (): A; + [Symbol.iterator](): { +>[Symbol.iterator] : () => { next(...args: ReadonlyArray): IteratorResult; } +> : ^^^^^^ +>Symbol.iterator : unique symbol +> : ^^^^^^^^^^^^^ +>Symbol : SymbolConstructor +> : ^^^^^^^^^^^^^^^^^ +>iterator : unique symbol +> : ^^^^^^^^^^^^^ + + next(...args: ReadonlyArray): IteratorResult; +>next : (...args: ReadonlyArray) => IteratorResult +> : ^^^^ ^^ ^^^^^ +>args : readonly any[] +> : ^^^^^^^^^^^^^^ + + }; + }; +}; + +declare function outer(body: (value: A) => Generator): void; +>outer : (body: (value: A) => Generator) => void +> : ^ ^^ ^^ ^^^^^ +>body : (value: A) => Generator +> : ^ ^^ ^^^^^ +>value : A +> : ^ + +outer(function* (value: T) { +>outer(function* (value: T) { const result = yield* inner(value); // ok}) : void +> : ^^^^ +>outer : (body: (value: A) => Generator) => void +> : ^ ^^ ^^ ^^^^^ +>function* (value: T) { const result = yield* inner(value); // ok} : (value: T) => Generator +> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>value : T +> : ^ + + const result = yield* inner(value); // ok +>result : T +> : ^ +>yield* inner(value) : T +> : ^ +>inner(value) : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray): IteratorResult; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner : (value: A) => { (): A; [Symbol.iterator](): { next(...args: ReadonlyArray): IteratorResult; }; } +> : ^ ^^ ^^ ^^^^^ +>value : T +> : ^ + +}); + +outer(function* (value: T) { +>outer(function* (value: T) { const x = inner(value); const result = yield* x; // ok}) : void +> : ^^^^ +>outer : (body: (value: A) => Generator) => void +> : ^ ^^ ^^ ^^^^^ +>function* (value: T) { const x = inner(value); const result = yield* x; // ok} : (value: T) => Generator +> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>value : T +> : ^ + + const x = inner(value); +>x : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray): IteratorResult; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner(value) : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray): IteratorResult; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner : (value: A) => { (): A; [Symbol.iterator](): { next(...args: ReadonlyArray): IteratorResult; }; } +> : ^ ^^ ^^ ^^^^^ +>value : T +> : ^ + + const result = yield* x; // ok +>result : T +> : ^ +>yield* x : T +> : ^ +>x : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray): IteratorResult; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +}); + +declare const inner2: { +>inner2 : (value: A) => () => A +> : ^ ^^ ^^ ^^^^^ + + (value: A): () => A; +>value : A +> : ^ + +}; + +outer(function* (value: T) { +>outer(function* (value: T) { const result = yield* inner2(value); // error}) : void +> : ^^^^ +>outer : (body: (value: A) => Generator) => void +> : ^ ^^ ^^ ^^^^^ +>function* (value: T) { const result = yield* inner2(value); // error} : (value: T) => Generator +> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>value : T +> : ^ + + const result = yield* inner2(value); // error +>result : any +> : ^^^ +>yield* inner2(value) : any +> : ^^^ +>inner2(value) : () => T +> : ^^^^^^^ +>inner2 : (value: A) => () => A +> : ^ ^^ ^^ ^^^^^ +>value : T +> : ^ + +}); + diff --git a/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall2.symbols b/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall2.symbols new file mode 100644 index 0000000000000..4b4628403a2e1 --- /dev/null +++ b/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall2.symbols @@ -0,0 +1,111 @@ +//// [tests/cases/compiler/genericCallAtYieldExpressionInGenericCall2.ts] //// + +=== genericCallAtYieldExpressionInGenericCall2.ts === +interface Effect { +>Effect : Symbol(Effect, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 0, 0)) + + [Symbol.iterator](): { +>[Symbol.iterator] : Symbol(Effect[Symbol.iterator], Decl(genericCallAtYieldExpressionInGenericCall2.ts, 0, 18)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + next(...args: ReadonlyArray): IteratorResult; +>next : Symbol(next, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 1, 24)) +>args : Symbol(args, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 2, 9)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --) ... and 3 more) +>IteratorResult : Symbol(IteratorResult, Decl(lib.es2015.iterable.d.ts, --, --)) + + }; +} + +interface Enqueue { +>Enqueue : Symbol(Enqueue, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 4, 1)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 6, 18)) + + offer: (value: A) => Effect; +>offer : Symbol(Enqueue.offer, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 6, 22)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 7, 10)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 6, 18)) +>Effect : Symbol(Effect, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 0, 0)) +} + +declare const offer: { +>offer : Symbol(offer, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 10, 13)) + + (value: A): (self: Enqueue) => Effect; +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 11, 3)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 11, 6)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 11, 3)) +>self : Symbol(self, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 11, 18)) +>Enqueue : Symbol(Enqueue, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 4, 1)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 11, 3)) +>Effect : Symbol(Effect, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 0, 0)) + + (self: Enqueue, value: A): Effect; +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 12, 3)) +>self : Symbol(self, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 12, 6)) +>Enqueue : Symbol(Enqueue, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 4, 1)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 12, 3)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 12, 23)) +>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 12, 3)) +>Effect : Symbol(Effect, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 0, 0)) + +}; + +declare function fn>( +>fn : Symbol(fn, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 13, 2)) +>Eff : Symbol(Eff, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 15, 20)) +>Effect : Symbol(Effect, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 0, 0)) +>AEff : Symbol(AEff, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 15, 39)) +>Args : Symbol(Args, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 15, 45)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 4 more) + + body: (...args: Args) => Generator, +>body : Symbol(body, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 15, 71)) +>args : Symbol(args, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 16, 9)) +>Args : Symbol(Args, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 15, 45)) +>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --)) +>Eff : Symbol(Eff, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 15, 20)) +>AEff : Symbol(AEff, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 15, 39)) + +): (...args: Args) => any; +>args : Symbol(args, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 17, 4)) +>Args : Symbol(Args, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 15, 45)) + +fn(function* (queue: Enqueue, value: T) { +>fn : Symbol(fn, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 13, 2)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 19, 14)) +>queue : Symbol(queue, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 19, 17)) +>Enqueue : Symbol(Enqueue, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 4, 1)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 19, 14)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 19, 35)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 19, 14)) + + yield* offer(queue, value); +>offer : Symbol(offer, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 10, 13)) +>queue : Symbol(queue, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 19, 17)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 19, 35)) + +}); + +fn(function* (queue: Enqueue, value: T) { +>fn : Symbol(fn, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 13, 2)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 23, 14)) +>queue : Symbol(queue, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 23, 17)) +>Enqueue : Symbol(Enqueue, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 4, 1)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 23, 14)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 23, 35)) +>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 23, 14)) + + const x = offer(queue, value); +>x : Symbol(x, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 24, 7)) +>offer : Symbol(offer, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 10, 13)) +>queue : Symbol(queue, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 23, 17)) +>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 23, 35)) + + yield* x; +>x : Symbol(x, Decl(genericCallAtYieldExpressionInGenericCall2.ts, 24, 7)) + +}); + diff --git a/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall2.types b/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall2.types new file mode 100644 index 0000000000000..35d2c2809705b --- /dev/null +++ b/tests/baselines/reference/genericCallAtYieldExpressionInGenericCall2.types @@ -0,0 +1,123 @@ +//// [tests/cases/compiler/genericCallAtYieldExpressionInGenericCall2.ts] //// + +=== Performance Stats === +Type Count: 1,000 +Instantiation count: 2,500 + +=== genericCallAtYieldExpressionInGenericCall2.ts === +interface Effect { + [Symbol.iterator](): { +>[Symbol.iterator] : () => { next(...args: ReadonlyArray): IteratorResult; } +> : ^^^^^^ +>Symbol.iterator : unique symbol +> : ^^^^^^^^^^^^^ +>Symbol : SymbolConstructor +> : ^^^^^^^^^^^^^^^^^ +>iterator : unique symbol +> : ^^^^^^^^^^^^^ + + next(...args: ReadonlyArray): IteratorResult; +>next : (...args: ReadonlyArray) => IteratorResult +> : ^^^^ ^^ ^^^^^ +>args : readonly any[] +> : ^^^^^^^^^^^^^^ + + }; +} + +interface Enqueue { + offer: (value: A) => Effect; +>offer : (value: A) => Effect +> : ^ ^^ ^^^^^ +>value : A +> : ^ +} + +declare const offer: { +>offer : { (value: A): (self: Enqueue) => Effect; (self: Enqueue, value: A): Effect; } +> : ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ + + (value: A): (self: Enqueue) => Effect; +>value : A +> : ^ +>self : Enqueue +> : ^^^^^^^^^^ + + (self: Enqueue, value: A): Effect; +>self : Enqueue +> : ^^^^^^^^^^ +>value : A +> : ^ + +}; + +declare function fn>( +>fn : >(body: (...args: Args) => Generator) => (...args: Args) => any +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ + + body: (...args: Args) => Generator, +>body : (...args: Args) => Generator +> : ^^^^ ^^ ^^^^^ +>args : Args +> : ^^^^ + +): (...args: Args) => any; +>args : Args +> : ^^^^ + +fn(function* (queue: Enqueue, value: T) { +>fn(function* (queue: Enqueue, value: T) { yield* offer(queue, value);}) : (queue: Enqueue, value: T) => any +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>fn : >(body: (...args: Args) => Generator) => (...args: Args) => any +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>function* (queue: Enqueue, value: T) { yield* offer(queue, value);} : (queue: Enqueue, value: T) => Generator +> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>queue : Enqueue +> : ^^^^^^^^^^ +>value : T +> : ^ + + yield* offer(queue, value); +>yield* offer(queue, value) : any +>offer(queue, value) : Effect +> : ^^^^^^ +>offer : { (value: A): (self: Enqueue) => Effect; (self: Enqueue, value: A): Effect; } +> : ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>queue : Enqueue +> : ^^^^^^^^^^ +>value : T +> : ^ + +}); + +fn(function* (queue: Enqueue, value: T) { +>fn(function* (queue: Enqueue, value: T) { const x = offer(queue, value); yield* x;}) : (queue: Enqueue, value: T) => any +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>fn : >(body: (...args: Args) => Generator) => (...args: Args) => any +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>function* (queue: Enqueue, value: T) { const x = offer(queue, value); yield* x;} : (queue: Enqueue, value: T) => Generator +> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>queue : Enqueue +> : ^^^^^^^^^^ +>value : T +> : ^ + + const x = offer(queue, value); +>x : Effect +> : ^^^^^^ +>offer(queue, value) : Effect +> : ^^^^^^ +>offer : { (value: A): (self: Enqueue) => Effect; (self: Enqueue, value: A): Effect; } +> : ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>queue : Enqueue +> : ^^^^^^^^^^ +>value : T +> : ^ + + yield* x; +>yield* x : any +>x : Effect +> : ^^^^^^ + +}); + diff --git a/tests/cases/compiler/genericCallAtYieldExpressionInGenericCall1.ts b/tests/cases/compiler/genericCallAtYieldExpressionInGenericCall1.ts new file mode 100644 index 0000000000000..cf7f97be34c69 --- /dev/null +++ b/tests/cases/compiler/genericCallAtYieldExpressionInGenericCall1.ts @@ -0,0 +1,32 @@ +// @strict: true +// @target: esnext +// @lib: esnext +// @noEmit: true + +declare const inner: { + (value: A): { + (): A; + [Symbol.iterator](): { + next(...args: ReadonlyArray): IteratorResult; + }; + }; +}; + +declare function outer(body: (value: A) => Generator): void; + +outer(function* (value: T) { + const result = yield* inner(value); // ok +}); + +outer(function* (value: T) { + const x = inner(value); + const result = yield* x; // ok +}); + +declare const inner2: { + (value: A): () => A; +}; + +outer(function* (value: T) { + const result = yield* inner2(value); // error +}); diff --git a/tests/cases/compiler/genericCallAtYieldExpressionInGenericCall2.ts b/tests/cases/compiler/genericCallAtYieldExpressionInGenericCall2.ts new file mode 100644 index 0000000000000..e01a2d90bcd89 --- /dev/null +++ b/tests/cases/compiler/genericCallAtYieldExpressionInGenericCall2.ts @@ -0,0 +1,32 @@ +// @strict: true +// @target: esnext +// @lib: esnext +// @noEmit: true + +interface Effect { + [Symbol.iterator](): { + next(...args: ReadonlyArray): IteratorResult; + }; +} + +interface Enqueue { + offer: (value: A) => Effect; +} + +declare const offer: { + (value: A): (self: Enqueue) => Effect; + (self: Enqueue, value: A): Effect; +}; + +declare function fn>( + body: (...args: Args) => Generator, +): (...args: Args) => any; + +fn(function* (queue: Enqueue, value: T) { + yield* offer(queue, value); +}); + +fn(function* (queue: Enqueue, value: T) { + const x = offer(queue, value); + yield* x; +});