Skip to content

Fix generic constraint matching for method-shaped receivers#273

Merged
ASDAlexander77 merged 1 commit into
mainfrom
fix/iterator-helper-extension-constraint-mismatch
Jul 21, 2026
Merged

Fix generic constraint matching for method-shaped receivers#273
ASDAlexander77 merged 1 commit into
mainfrom
fix/iterator-helper-extension-constraint-mismatch

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Summary

  • extendsTypeFuncTypes skipped the receiver's bound this param when comparing against a method-shaped generic constraint (e.g. TIter extends { next(): {...} }), but never skipped the constraint's own leading this placeholder (OpaqueType) in lockstep — misaligning the two parameter lists by one and causing every subsequent parameter comparison to fail (collapsing to <<NULL TYPE>> vs !ts.opaque).
  • This blocked any extension method whose generic constraint requires a method-shaped field on the receiver — concretely, TypeScriptCompilerDefaultLib's __Iterator.take/drop/every/filter/find/forEach/map/reduce/some/toArray never resolved on generator (function*) return types (fibonacci().take(5), fibonacci().every(fn), etc. all failed to compile).
  • Also added ObjectType/ObjectStorageType cases to getFieldTypeByFieldName so a boxed generator return type exposes its fields (e.g. next()) to structural constraint checks in the first place.

Root-caused via LLVM debug tracing (-debug-only=mlir) on a Debug JIT build, isolating the exact extendsType recursion where the receiver's next() method type was compared against the constraint's next() signature and one side's parameter came back null.

Test plan

  • Rebuilt tslang (Debug + Release) with the fix
  • Ran TypeScriptCompilerDefaultLib's full tests.ps1 suite (release/debug × compile/jit, 150 tests × 4 = 600 runs): 150/150 passing on all four, including the 10 previously-failing iterator_*.ts tests (iterator_drop/every/filter/find/forEach/map/reduce/some/take/toArray)
  • No regressions in the other 140 tests

🤖 Generated with Claude Code

…am misalignment)

extendsTypeFuncTypes skipped the receiver's bound `this` param when
comparing against a method-shaped constraint (e.g. `T extends { next(): ... }`),
but never skipped the constraint's own leading `this` placeholder (OpaqueType)
in lockstep. That misaligned the two param lists by one, so every extension
method whose generic constraint required a method field (e.g. DefaultLib's
__Iterator.take/drop/every/filter/find/forEach/map/reduce/some/toArray on
generator return types) failed to resolve.

Also add ObjectType/ObjectStorageType cases to getFieldTypeByFieldName so
boxed generator return types expose their fields to structural constraint
checks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit 6c98e8d into main Jul 21, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the fix/iterator-helper-extension-constraint-mismatch branch July 21, 2026 17:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant