From 9f24b2be89a10fa4726348733a407bd0fe210887 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 23:51:35 +0000 Subject: [PATCH 1/2] Initial plan From cca56dbfe68b0fc95fe2142fcc5c02c2a2fca850 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 00:06:26 +0000 Subject: [PATCH 2/2] Port TypeScript PR #62283: Avoid silentNeverType leaking into generator types Clear CheckModeSkipGenericFunctions flag when checking yield expressions in checkAndAggregateYieldOperandTypes, preventing silentNeverType from leaking into inferred generator types based on inner generic calls. Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com> --- internal/checker/checker.go | 2 +- ...AtYieldExpressionInGenericCall1.errors.txt | 38 +++------ ...ldExpressionInGenericCall1.errors.txt.diff | 82 +++---------------- ...cCallAtYieldExpressionInGenericCall1.types | 8 +- ...AtYieldExpressionInGenericCall1.types.diff | 25 +----- ...AtYieldExpressionInGenericCall2.errors.txt | 34 -------- ...ldExpressionInGenericCall2.errors.txt.diff | 38 --------- 7 files changed, 34 insertions(+), 193 deletions(-) delete mode 100644 testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall2.errors.txt delete mode 100644 testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall2.errors.txt.diff diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 07e11109bf7..e814bf1a2d1 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -19852,7 +19852,7 @@ func (c *Checker) checkAndAggregateYieldOperandTypes(fn *ast.Node, checkMode Che forEachYieldExpression(fn.Body(), func(yieldExpr *ast.Node) { yieldExprType := c.undefinedWideningType if yieldExpr.Expression() != nil { - yieldExprType = c.checkExpressionEx(yieldExpr.Expression(), checkMode) + yieldExprType = c.checkExpressionEx(yieldExpr.Expression(), checkMode & ^CheckModeSkipGenericFunctions) } if yieldExpr.Expression() != nil && c.isConstContext(yieldExpr.Expression()) { yieldExprType = c.getRegularTypeOfLiteralType(yieldExprType) diff --git a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.errors.txt b/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.errors.txt index 9322654c015..7462751ad1a 100644 --- a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.errors.txt +++ b/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.errors.txt @@ -1,15 +1,11 @@ -genericCallAtYieldExpressionInGenericCall1.ts(13,25): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. genericCallAtYieldExpressionInGenericCall1.ts(26,25): error TS2488: Type '() => T' must have a '[Symbol.iterator]()' method that returns an iterator. -genericCallAtYieldExpressionInGenericCall1.ts(26,25): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. -genericCallAtYieldExpressionInGenericCall1.ts(42,10): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. -genericCallAtYieldExpressionInGenericCall1.ts(56,8): error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. - Type 'Generator' is not assignable to type 'Generator'. +genericCallAtYieldExpressionInGenericCall1.ts(56,8): error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. + Type 'Generator' is not assignable to type 'Generator'. The types returned by 'next(...)' are incompatible between these types. - Type 'IteratorResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. - Type 'any' is not assignable to type 'never'. -genericCallAtYieldExpressionInGenericCall1.ts(57,10): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. + Type 'IteratorResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. + Type 'number' is not assignable to type 'never'. genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. Type 'Generator' is not assignable to type 'Generator'. The types returned by 'next(...)' are incompatible between these types. @@ -19,7 +15,7 @@ genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of t Type 'number' is not assignable to type 'never'. -==== genericCallAtYieldExpressionInGenericCall1.ts (7 errors) ==== +==== genericCallAtYieldExpressionInGenericCall1.ts (3 errors) ==== declare const inner: { (value: A): { (): A; @@ -33,8 +29,6 @@ genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of t outer(function* (value: T) { const result = yield* inner(value); // ok - ~~~~~~~~~~~~ -!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. }); outer(function* (value: T) { @@ -50,8 +44,6 @@ genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of t const result = yield* inner2(value); // error ~~~~~~~~~~~~~ !!! error TS2488: Type '() => T' must have a '[Symbol.iterator]()' method that returns an iterator. - ~~~~~~~~~~~~~ -!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. }); declare const inner3: { @@ -68,8 +60,6 @@ genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of t // number const result1 = outer2(function* (value: T) { yield* inner3(value); - ~~~~~~~~~~~~~ -!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. }); // number @@ -85,16 +75,14 @@ genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of t // error outer3(function* (value: T) { ~~~~~~~~ -!!! error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. -!!! error TS2345: Type 'Generator' is not assignable to type 'Generator'. +!!! error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. +!!! error TS2345: Type 'Generator' is not assignable to type 'Generator'. !!! error TS2345: The types returned by 'next(...)' are incompatible between these types. -!!! error TS2345: Type 'IteratorResult' is not assignable to type 'IteratorResult'. -!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. -!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. -!!! error TS2345: Type 'any' is not assignable to type 'never'. +!!! error TS2345: Type 'IteratorResult' is not assignable to type 'IteratorResult'. +!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. +!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. +!!! error TS2345: Type 'number' is not assignable to type 'never'. yield* inner3(value); - ~~~~~~~~~~~~~ -!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. }); // error diff --git a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.errors.txt.diff index b376a093e62..dd9c3f3c8ff 100644 --- a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.errors.txt.diff +++ b/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.errors.txt.diff @@ -1,89 +1,31 @@ --- old.genericCallAtYieldExpressionInGenericCall1.errors.txt +++ new.genericCallAtYieldExpressionInGenericCall1.errors.txt @@= skipped -0, +0 lines =@@ -+genericCallAtYieldExpressionInGenericCall1.ts(13,25): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. genericCallAtYieldExpressionInGenericCall1.ts(26,25): error TS2488: Type '() => T' must have a '[Symbol.iterator]()' method that returns an iterator. --genericCallAtYieldExpressionInGenericCall1.ts(56,8): error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. + genericCallAtYieldExpressionInGenericCall1.ts(56,8): error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. - Call signature return types 'Generator' and 'Generator' are incompatible. -+genericCallAtYieldExpressionInGenericCall1.ts(26,25): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. -+genericCallAtYieldExpressionInGenericCall1.ts(42,10): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. -+genericCallAtYieldExpressionInGenericCall1.ts(56,8): error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. -+ Type 'Generator' is not assignable to type 'Generator'. ++ Type 'Generator' is not assignable to type 'Generator'. The types returned by 'next(...)' are incompatible between these types. -- Type 'IteratorResult' is not assignable to type 'IteratorResult'. -- Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. -- Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. -- Type 'number' is not assignable to type 'never'. -+ Type 'IteratorResult' is not assignable to type 'IteratorResult'. -+ Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. -+ Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. -+ Type 'any' is not assignable to type 'never'. -+genericCallAtYieldExpressionInGenericCall1.ts(57,10): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. + Type 'IteratorResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. + Type 'number' is not assignable to type 'never'. genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. - Call signature return types 'Generator' and 'Generator' are incompatible. + Type 'Generator' is not assignable to type 'Generator'. The types returned by 'next(...)' are incompatible between these types. Type 'IteratorResult' is not assignable to type 'IteratorResult'. Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. -@@= skipped -14, +18 lines =@@ - Type 'number' is not assignable to type 'never'. - - --==== genericCallAtYieldExpressionInGenericCall1.ts (3 errors) ==== -+==== genericCallAtYieldExpressionInGenericCall1.ts (7 errors) ==== - declare const inner: { - (value: A): { - (): A; -@@= skipped -14, +14 lines =@@ - - outer(function* (value: T) { - const result = yield* inner(value); // ok -+ ~~~~~~~~~~~~ -+!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. - }); - - outer(function* (value: T) { -@@= skipped -15, +17 lines =@@ - const result = yield* inner2(value); // error - ~~~~~~~~~~~~~ - !!! error TS2488: Type '() => T' must have a '[Symbol.iterator]()' method that returns an iterator. -+ ~~~~~~~~~~~~~ -+!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. - }); - - declare const inner3: { -@@= skipped -16, +18 lines =@@ - // number - const result1 = outer2(function* (value: T) { - yield* inner3(value); -+ ~~~~~~~~~~~~~ -+!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. - }); - - // number -@@= skipped -15, +17 lines =@@ - // error +@@= skipped -75, +75 lines =@@ outer3(function* (value: T) { ~~~~~~~~ --!!! error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. + !!! error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. -!!! error TS2345: Call signature return types 'Generator' and 'Generator' are incompatible. -+!!! error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. -+!!! error TS2345: Type 'Generator' is not assignable to type 'Generator'. ++!!! error TS2345: Type 'Generator' is not assignable to type 'Generator'. !!! error TS2345: The types returned by 'next(...)' are incompatible between these types. --!!! error TS2345: Type 'IteratorResult' is not assignable to type 'IteratorResult'. --!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. --!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. --!!! error TS2345: Type 'number' is not assignable to type 'never'. -+!!! error TS2345: Type 'IteratorResult' is not assignable to type 'IteratorResult'. -+!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. -+!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. -+!!! error TS2345: Type 'any' is not assignable to type 'never'. - yield* inner3(value); -+ ~~~~~~~~~~~~~ -+!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. - }); - - // error + !!! error TS2345: Type 'IteratorResult' is not assignable to type 'IteratorResult'. + !!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. +@@= skipped -13, +13 lines =@@ outer3(function* (value: T) { ~~~~~~~~ !!! error TS2345: Argument of type '(value: T) => Generator' is not assignable to parameter of type '(value: unknown) => Generator'. diff --git a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.types b/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.types index d30d2bde20d..fc23bf05152 100644 --- a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.types +++ b/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.types @@ -112,10 +112,10 @@ declare function outer2(body: (value: A) => Generator): Y; // number const result1 = outer2(function* (value: T) { ->result1 : any ->outer2(function* (value: T) { yield* inner3(value);}) : any +>result1 : number +>outer2(function* (value: T) { yield* inner3(value);}) : number >outer2 : (body: (value: A) => Generator) => Y ->function* (value: T) { yield* inner3(value);} : (value: T) => Generator +>function* (value: T) { yield* inner3(value);} : (value: T) => Generator >value : T yield* inner3(value); @@ -159,7 +159,7 @@ declare function outer3( outer3(function* (value: T) { >outer3(function* (value: T) { yield* inner3(value);}) : void >outer3 : (body: (value: A) => Generator) => void ->function* (value: T) { yield* inner3(value);} : (value: T) => Generator +>function* (value: T) { yield* inner3(value);} : (value: T) => Generator >value : T yield* inner3(value); diff --git a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.types.diff b/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.types.diff index 8ca6f4b25ba..52406099d64 100644 --- a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.types.diff +++ b/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall1.types.diff @@ -79,18 +79,7 @@ >args : readonly any[] }; -@@= skipped -27, +27 lines =@@ - - // number - const result1 = outer2(function* (value: T) { -->result1 : number -->outer2(function* (value: T) { yield* inner3(value);}) : number -+>result1 : any -+>outer2(function* (value: T) { yield* inner3(value);}) : any - >outer2 : (body: (value: A) => Generator) => Y -->function* (value: T) { yield* inner3(value);} : (value: T) => Generator -+>function* (value: T) { yield* inner3(value);} : (value: T) => Generator - >value : T +@@= skipped -35, +35 lines =@@ yield* inner3(value); >yield* inner3(value) : T @@ -101,7 +90,7 @@ >value : T }); -@@= skipped -23, +23 lines =@@ +@@= skipped -15, +15 lines =@@ >value : T const x = inner3(value); @@ -120,13 +109,7 @@ }); -@@= skipped -24, +24 lines =@@ - outer3(function* (value: T) { - >outer3(function* (value: T) { yield* inner3(value);}) : void - >outer3 : (body: (value: A) => Generator) => void -->function* (value: T) { yield* inner3(value);} : (value: T) => Generator -+>function* (value: T) { yield* inner3(value);} : (value: T) => Generator - >value : T +@@= skipped -29, +29 lines =@@ yield* inner3(value); >yield* inner3(value) : T @@ -137,7 +120,7 @@ >value : T }); -@@= skipped -19, +19 lines =@@ +@@= skipped -14, +14 lines =@@ >value : T const x = inner3(value); diff --git a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall2.errors.txt b/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall2.errors.txt deleted file mode 100644 index da5db184e7e..00000000000 --- a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall2.errors.txt +++ /dev/null @@ -1,34 +0,0 @@ -genericCallAtYieldExpressionInGenericCall2.ts(21,10): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. - - -==== genericCallAtYieldExpressionInGenericCall2.ts (1 errors) ==== - 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); - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. - }); - - fn(function* (queue: Enqueue, value: T) { - const x = offer(queue, value); - yield* x; - }); - \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall2.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall2.errors.txt.diff deleted file mode 100644 index a754dea615b..00000000000 --- a/testdata/baselines/reference/submodule/compiler/genericCallAtYieldExpressionInGenericCall2.errors.txt.diff +++ /dev/null @@ -1,38 +0,0 @@ ---- old.genericCallAtYieldExpressionInGenericCall2.errors.txt -+++ new.genericCallAtYieldExpressionInGenericCall2.errors.txt -@@= skipped -0, +0 lines =@@ -- -+genericCallAtYieldExpressionInGenericCall2.ts(21,10): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. -+ -+ -+==== genericCallAtYieldExpressionInGenericCall2.ts (1 errors) ==== -+ 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); -+ ~~~~~~~~~~~~~~~~~~~ -+!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator. -+ }); -+ -+ fn(function* (queue: Enqueue, value: T) { -+ const x = offer(queue, value); -+ yield* x; -+ }); -+ \ No newline at end of file