[whatwg/webidl] Converting to Promise<T>: implementations return existing promises instead of creating new ones (Issue #1656)

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