emit-tsd: add TSD_SKIP_EXPORTS for toolchain-owned exports; warn on unhandled multi-value returns#26966
emit-tsd: add TSD_SKIP_EXPORTS for toolchain-owned exports; warn on unhandled multi-value returns#26966guybedford wants to merge 1 commit into
Conversation
…nhandled multi-value returns When a higher-level toolchain (e.g. wasm-bindgen) lowers compound types to wasm-level (ptr, len) tuples and installs its own JS wrapper via --js-library, emcc has no way to recover the user-facing JS type from the raw wasm signature. Today --emit-tsd asserts on those exports. Add TSD_SKIP_EXPORTS so the toolchain can list the exports it owns. Multi-value-return exports not on the list are skipped with a warning instead of crashing the build.
8fdb1c5 to
7bc151b
Compare
|
Welcome @guybedford ! Thanks for the PR. Assigning @brendandahl who has done most of the tsc compiler work. My main concern here is the addition of a new setting in the compiler. Every time we add another entry to |
|
Thanks @sbc100 and @brendandahl for taking a look. Actually on second thoughts I think we can avoid this approach entirely by just maintaining the typing entirely on the wasm bindgen side here. That is, @walkingeyerobot's work on the other hand was based on having Closing for now, but if this comes up again I'll let you know. |
Today
--emit-tsdasserts when it sees a wasm function with multiple return values:This fails for any wasm produced by a higher-level toolchain that lowers compound types to wasm-level (ptr, len)-style tuples. wasm-bindgen is the canonical case — Rust exports returning
String,Vec<u8>,Result<T, E>etc. all show up as(i32, i32)in the wasm. The user-facing JS surface for those exports isn't the wasm export at all; it's a JS wrapper installed via--js-library, and the wrapping toolchain declares the real type in its own.d.ts. emcc has no way to recover that type from the wasm signature, so guessing (e.g. a tuple) is wrong and silently skipping is opaque.Give the toolchain a way to tell emcc which exports it owns: a new
TSD_SKIP_EXPORTSsetting listing wasm export names to omit from--emit-tsd. Exports on the list are skipped silently. Multi-value-return exports not on the list are skipped with an actionable warning rather than asserting, so the toolchain hears about anything it forgot to declare without the build crashing. Single- and void-return exports are typed as before.This composes naturally with downstream
.d.tsmergers (e.g. wasm-pack's emscripten flow) which layer the toolchain's.d.tson top of emcc's to supply the real types for the skipped exports.Tests cover the four scenarios: skipped export omitted with no warning, unhandled multi-value export omitted with a warning, unknown skip-list entries silently ignored, and the existing single-return path unchanged.