Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seeking clarification on whether unioning promises and callbacks is allowed #1278

Closed
sanketj opened this issue Mar 9, 2023 · 2 comments
Closed

Comments

@sanketj
Copy link
Member

sanketj commented Mar 9, 2023

While trying to make some IDL updates to the ClipboardItem constructor in Chromium (https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/clipboard/clipboard_item.idl), we discovered that the Chromium IDL compiler failed to union a promise and callback, or even just multiple promises, together. We tried a few other cases where we unioned promises and/or callbacks with other types, and those seemed to work. Below is a list of what did work and what didn't.

typedef Promise<Blob> ClipboardBlobPromise;
typedef Promise<DOMString> ClipboardStringPromise;
callback ClipboardBlobCallback = Blob();
callback ClipboardStringCallback = DOMString();

typedef (Blob or DOMString) ClipboardItemData; // works
typedef (ClipboardBlobPromise or DOMString) ClipboardItemData; // works
typedef (Blob or ClipboardStringPromise) ClipboardItemData; // works
typedef (ClipboardBlobPromise or ClipboardStringPromise) ClipboardItemData; // does not work
typedef (Blob or ClipboardStringCallback) ClipboardItemData; // works
typedef (ClipboardBlobCallback or DOMString) ClipboardItemData; // works
typedef (ClipboardBlobCallback or ClipboardStringCallback) ClipboardItemData; // works
typedef (ClipboardBlobPromise or ClipboardBlobCallback) ClipboardItemData; // does not work

constructor(record<DOMString, ClipboardItemData> items);

Based on the above examples that do work, as well as reading through the WebIDL spec, it does not look like there should be any limitations on callback function types or promise types participating in unions. Does this sound like a bug in the Chromium WebIDL compiler, or is there anything in the spec that should prevent such cases from working?

cc: @snianu, @anaskim

@bathos
Copy link
Contributor

bathos commented Mar 9, 2023

Promise types are indistinguishable from every type and thus cannot be members of unions, at least as currently specified. This follows from the fact that e.g. 3 is a valid ECMAScript input for Promise<byte> — it’s like await 3 or Promise.resolve(3).

This issue about possibly changing the ES→WI conversion of Promise<T> to special case functions may be of interest, but that’s about whether to assume any callable input wants to be called in this scenario (e.g. async functions) for the ergonomic benefit.

Note that while (Promise<Blob> or Promise<DOMString> or Promise<SomeCallback>) is incoherent, Promise<(Blob or DOMString or SomeCallback)> isn’t. For similar reasons, two different callbacks cannot be members of one union, but one callback that returns the union of the return types would be fine:

callback ClipboardCallback = (Blob or DOMString) ();

These two “works” cases from above imply errors in Blink’s implementation because these are invalid Web IDL types which don’t have defined conversion behavior:

typedef (Blob or ClipboardStringPromise) ClipboardItemData; // works
typedef (ClipboardBlobCallback or ClipboardStringCallback) ClipboardItemData; // works

(I’m assuming that typedef Promise ClipboardBlobPromise (etc) were meant to say typedef Promise<Blob> ClipboardBlobPromise)


It sounds like you might want something like this? —

typedef (Blob or DOMString) ClipboardItemValue;
typedef Promise<(ClipboardItemValue or ClipboardItemValueCallback)> ClipboardItemInit;

callback ClipboardItemValueCallback = ClipboardItemValue ();

// ...
constructor(record<DOMString, ClipboardItemInit> items);

@sanketj
Copy link
Member Author

sanketj commented Mar 9, 2023

Yes, I did mean typedef Promise<Blob> ClipboardBlobPromise instead of typedef Promise ClipboardBlobPromise. I've fixed that in the original post too.

Thanks for the clarifications @bathos! Those explanations all make sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants