Lower async return primitives to js_sys wrappers#14
Merged
guybedford merged 2 commits intoApr 29, 2026
Conversation
`pub async fn -> Result<T, JsValue>` requires `T: JsGeneric` (an externref-backed type) under the workers-rs wasm-bindgen fork. Rust primitives don't satisfy that bound, so emitting `Result<bool|f64|String, JsValue>` for `Promise<boolean|number|string>` fails to compile under that flavour. Lower these primitives to their `js_sys` wrapper types — `Boolean`, `Number`, `JsString` — in async return position only. The wrappers ARE externref-backed and pass the JsGeneric bound. Callers recover the Rust primitive via `.value_of()` (Boolean / Number) or `String::from(_)` (JsString). The lowering is scoped to async returns: arguments, properties, and sync returns continue to use Rust primitives. Void returns stay as `()`, named JS types stay as themselves, JsValue stays as JsValue — the constraint only bites for primitives wrapped by `Promise<T>`. Snapshot impact: 36 async primitive returns across the four fixtures shift to JS wrapper types. Public API for callers changes from `Result<bool, JsValue>` to `Result<Boolean, JsValue>` etc., trading one `.value_of()` call at the call site for portability across wasm-bindgen flavours and a single extern (no Rust-side cast logic).
guybedford
reviewed
Apr 29, 2026
guybedford
approved these changes
Apr 29, 2026
guybedford
left a comment
Contributor
There was a problem hiding this comment.
This is correct - and was even the nature of async fn in Wasm Bindgen before we added generics. JsGeneric just does require a JsValue / externref ABI so these types are the representations to do that.
If we hit real ergonomic issues though, please do bring them up.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Promise<T>/JsFuture<T>inwasm-bindgenrequireT: JsGeneric,which bare Rust primitives (
bool,f64,String) don't satisfy.primitives lower to
js_syswrappers (Boolean,Number,JsString,Undefined) andNullable<T>becomesJsOption<T>.is_asyncthroughto_return_typefrom the three call sitesin
codegen/{functions,classes}.rs(free fns, methods, static methods,constructors).
CONVENTIONS.md,including how callers recover primitives (
.value_of()forBoolean/Number,String::from(_)forJsString).basic,coverage,cloudflare-worker, andworkers-typesreflect the new wrapper-typed async signatures.