Skip to content

fix(ext/webidl): follow GetIterator semantics in async iterable converter#34872

Closed
crowlbot wants to merge 3 commits into
mainfrom
fix/readablestream-from-getiterator
Closed

fix(ext/webidl): follow GetIterator semantics in async iterable converter#34872
crowlbot wants to merge 3 commits into
mainfrom
fix/readablestream-from-getiterator

Conversation

@crowlbot

@crowlbot crowlbot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

The WebIDL async iterable converter (used by ReadableStream.from() and any
operation taking an async iterable<T> argument) did not follow the
GetIterator(obj, async) abstract operation:

  1. It rejected any non-Object value up front (type(V) !== "Object" throws),
    so primitives such as strings could never be converted, even though
    GetIterator performs ToObject(V) and strings are iterable.
  2. When looking up the @@asyncIterator / @@iterator methods it only treated
    undefined as "method absent". Per GetMethod, a null value must also be
    treated as absent, so a null @@asyncIterator should fall back to the sync
    @@iterator rather than being called.

This fix narrows the early rejection to only undefined/null (the values that
ToObject would reject) and treats both undefined and null method values as
absent, matching GetIterator / GetMethod.

Spec

WPT

Flips the following subtests from failing to passing under
streams/readable-streams/from.any.{html,worker.html} (+4 total):

  • ReadableStream.from accepts a string
  • ReadableStream.from ignores a null @@asyncIterator

Expectations in tests/wpt/runner/expectations/streams.json updated
accordingly (both from.any.html and from.any.worker.html now fully pass).

crowlbot added 3 commits June 5, 2026 03:48
…rter

The async iterable converter used by ReadableStream.from() rejected
non-Object values and only treated an `undefined` (not `null`)
@@asynciterator / @@iterator as an absent method.

Per the GetIterator(obj, async) abstract operation, the iterator methods
are looked up with GetMethod semantics, which (1) performs ToObject on
the value, so primitives such as strings are accepted, and (2) treats
both `undefined` and `null` as an absent method.

Fixes two WPT subtests in streams/readable-streams/from.any:
- ReadableStream.from accepts a string
- ReadableStream.from ignores a null @@asynciterator
The unit test asserted ReadableStream.from(string) throws, which was the
pre-spec behavior. Per the Streams spec it accepts any iterable, including
strings; update the test to assert characters are yielded.
The ReadableStream.from type signature requires an object, so passing a
string primitive is a static type error even though it is iterable at
runtime. Add a @ts-expect-error directive (matching the prior test).
@crowlKats

Copy link
Copy Markdown
Member

This is incorrect, see whatwg/webidl#1397, whatwg/streams#1372

@crowlKats crowlKats closed this Jun 8, 2026
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.

2 participants