Repository navigation
Accept private iterables in for..of - #8937
Conversation
Why:
`Generator.t`, `IteratorObject.t` and the other iterator types are
private abbreviations of `iterable`, so `for..of` rejected them and
needed `->asIterable` first.
`for..of` and `for await..of` now also unify the collection's type through
its private abbreviations, as an explicit `:>` would. Errors still report
the type as written.
Typing modified (for..of collection):
Before (rule):
Γ ⊢ e : iterable<τ> Γ, x : τ ⊢ body : unit
───────────────────────────────────────────── (for-of)
Γ ⊢ `for x of e { body }` : unit
After (rule):
Γ ⊢ e : σ σ ≤ iterable<τ> Γ, x : τ ⊢ body : unit
───────────────────────────────────────────────────── (for-of)
Γ ⊢ `for x of e { body }` : unit
Diagnostic removed (for..of over a generator):
Example:
let f = (g: Generator.t<int, string, unit>) =>
for x of g {
Console.log(x)
}
Before (diagnostic):
This has type:
Generator.t<int, string, unit>
But it's expected to have type: iterable<'a>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc7LEuyEfynjaKCVEBPmTF
Signed-off-by: Christoph Knittel <ck@cca.io>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #8937 +/- ##
=======================================
Coverage 81.13% 81.14%
=======================================
Files 456 456
Lines 63754 63766 +12
=======================================
+ Hits 51728 51740 +12
Misses 12026 12026
🚀 New features to boost your workflow:
|
rescript
@rescript/belt
@rescript/darwin-arm64
@rescript/linux-arm64
@rescript/linux-x64
@rescript/runtime
@rescript/win32-x64
commit: |
|
Developer playground preview: https://rescript-lang.github.io/rescript/dev-playground/?version=pr-8937 |
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
cristianoc
left a comment
There was a problem hiding this comment.
Pr description hard to follow.
Semantic diff much cleaner.
So yes @cknitt we can do the PR aspect too, soon.
Generator.t,IterableIterator.t,IteratorObject.t,AsyncGenerator.tandAsyncIterableIterator.tare private abbreviations ofiterable/asyncIterable(#8355). A private abbreviation doesn't unify with its expansion, so iterating one needed a conversion first:for..ofandfor await..ofnow also unify the collection's type through its private abbreviations, as an explicit:>would, sofor x of gworks. Only after the usual unification fails is the expansion tried, and a failure still reports the type as written. The generated JavaScript is unchanged.for await..ofnow types its collection first and then unifies, likefor..ofalready did, instead of typing it against the expected type. Its existing error fixture is unchanged.This only covers loops. Function arguments still need
asIterable(Array.fromIterable(gen)), since ReScript applies no implicit coercions there.Map.tandSet.tare abstract types, not private iterables, so they still needasIterableas well. Re-declaring them would drop their@notUndefined(which is only allowed on abstract types) and change howoption<Map.t<_>>is represented, so it is left for a separate change.Part of the groundwork for generator functions (#8934).
Test:
tests/tests/src/for_of_private_iterable_test.resiterates a generator (includingbreak), an iterator object fromArray.values, and an async generator withfor await.🤖 Generated with Claude Code
https://claude.ai/code/session_01Fc7LEuyEfynjaKCVEBPmTF