- From: Matthew Gaudet <notifications@github.com>
- Date: Wed, 28 Oct 2026 11:29:17 -0700
- To: whatwg/webidl <webidl@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/webidl/issues/1656@github.com>
mgaudet created an issue (whatwg/webidl#1656)
### What is the issue with the Web IDL Standard?
The current spec [reads](https://webidl.spec.whatwg.org/#js-promise):
> IDL promise type values are represented by JavaScript PromiseCapability records.
>
> A JavaScript value V is converted to an IDL Promise<T> value as follows:
>
> 1. Let promiseCapability be ? NewPromiseCapability(%Promise%).
> 2. Perform ? Call(promiseCapability.[[Resolve]], undefined, « V »).
> 3. return promiseCapability
The implication here is that whenever we convert some V to something of type Promise<T> we create a new promise.
As a result, by specification, if V is a promise, we take the ECMAScript promise adoption path, which results in an increase in the number of ticks, and no read of `constructor`.
What actually seems to be implemented in Safari and Firefox is instead closer to the below (though PromiseResolve doesn’t return a PromiseCapability)
> A JavaScript value V is converted to an IDL Promise<T> value as follows:
>
> 1. Return PromiseResolve(%Promise%, V)
Which has a is-promise-with-same-constructor fast path, and so will return V if it is a promise with %Promise% as its constructor, and reads constructor. (Safari actually seems to read constructor twice)
Chrome is a third behaviour: It doesn’t appear to read constructor at all, and will simply straight up return V if V is a promise subclass too.
A brief demo:
```js
const p = Promise.resolve();
Object.defineProperty(p, "constructor", { get() { console.log("get constructor"); return Promise; } });
const reader = new ReadableStream({ pull: () => p }, { highWaterMark: 0 }).getReader();
setTimeout(() => { reader.read(); console.log("read() returned"); });
// Spec: "read() returned", then "get constructor" (then() reads it in the adoption job).
// Firefox: "get constructor" first (PromiseResolve step 1.a).
// Safari: "get constructor" twice, before read returned.
// Chrome: never logged.
```
There also doesn’t really seem to be any WPT testing here.
This ends up being relevant to https://github.com/whatwg/webidl/pull/1645 as the experimental implementation of that PR in [Firefox missed conversion entirely](https://bugzilla.mozilla.org/show_bug.cgi?id=2085834), but me trying to resolve that bug highlighted the spec difference.
--
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/webidl/issues/1656
You are receiving this because you are subscribed to this thread.
Message ID: <whatwg/webidl/issues/1656@github.com>
Received on Wednesday, 28 October 2026 18:29:21 UTC