Skip to content

Lower async return primitives to js_sys wrappers#14

Merged
guybedford merged 2 commits into
wasm-bindgen:mainfrom
connyay:primitive-async-wrapper-redux
Apr 29, 2026
Merged

Lower async return primitives to js_sys wrappers#14
guybedford merged 2 commits into
wasm-bindgen:mainfrom
connyay:primitive-async-wrapper-redux

Conversation

@connyay

@connyay connyay commented Apr 29, 2026

Copy link
Copy Markdown
Contributor
  • Promise<T> / JsFuture<T> in wasm-bindgen require T: JsGeneric,
    which bare Rust primitives (bool, f64, String) don't satisfy.
    primitives lower to js_sys wrappers (Boolean, Number, JsString,
    Undefined) and Nullable<T> becomes JsOption<T>.
  • Threads is_async through to_return_type from the three call sites
    in codegen/{functions,classes}.rs (free fns, methods, static methods,
    constructors).
  • Documents the async-return lowering table in CONVENTIONS.md,
    including how callers recover primitives (.value_of() for
    Boolean/Number, String::from(_) for JsString).
  • Snapshot updates in basic, coverage, cloudflare-worker, and
    workers-types reflect the new wrapper-typed async signatures.

`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).
Comment thread src/codegen/typemap.rs Outdated
@connyay connyay changed the title Lower Promise<bool|number|string> to JS wrapper types in async returns Lower async return primitives to js_sys wrappers Apr 29, 2026

@guybedford guybedford left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@guybedford guybedford marked this pull request as ready for review April 29, 2026 23:33
@guybedford guybedford merged commit efa086a into wasm-bindgen:main Apr 29, 2026
4 checks passed
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