Skip to content

feat: add --panic-unwind flag to build and test commands#1572

Merged
guybedford merged 1 commit into
wasm-bindgen:masterfrom
guybedford:panic-unwind
May 13, 2026
Merged

feat: add --panic-unwind flag to build and test commands#1572
guybedford merged 1 commit into
wasm-bindgen:masterfrom
guybedford:panic-unwind

Conversation

@guybedford

Copy link
Copy Markdown
Contributor

This adds a new --panic-unwind flag to wasm-pack build and wasm-pack test so projects can opt in to building with -Cpanic=unwind instead of the default panic=abort.

Rust's default panic strategy on wasm32-unknown-unknown is abort, which terminates the WebAssembly instance on any panic. With nightly + -Zbuild-std, projects can now rebuild std with unwinding enabled, allowing bindings layers (e.g. wasm-bindgen's catch-unwind support) to convert panics into catchable JavaScript exceptions. Doing this manually requires plumbing several flags and ensuring the nightly toolchain has the right components — --panic-unwind collapses that into a single flag.

Worth noting up front: this is a build-tool-level enabler. It produces a .wasm compiled with unwinding semantics. The actual conversion of caught panics into JS exceptions is the responsibility of the consuming bindings layer; wasm-pack does not generate runtime shims for this.

When --panic-unwind is passed, cargo is invoked with:

cargo +nightly build --lib -Z build-std=std,panic_unwind …
RUSTFLAGS="${existing} -Cpanic=unwind"

Any pre-existing RUSTFLAGS value is preserved.

  • Adds --panic-unwind to BuildOptions and TestOptions
  • Threads it through to cargo_build_wasm / cargo_build_wasm_tests
  • Adds check_nightly_prerequisites() in src/build/wasm_target.rs that auto-installs the nightly toolchain, rust-src component, and nightly wasm32-unknown-unknown target via rustup when missing
  • Skips the stable step_check_rustc_version and step_check_for_wasm_target when --panic-unwind is set (the stable toolchain isn't invoked in that mode)
  • Documents the flag in docs/src/commands/build.md and docs/src/commands/test.md

Before:

cmd.arg("build").arg("--lib");
// stable toolchain only

After:

if panic_unwind {
    cmd.arg("+nightly");
}
cmd.arg("build").arg("--lib");
// later:
if panic_unwind {
    cmd.arg("-Z").arg("build-std=std,panic_unwind");
    cmd.env("RUSTFLAGS", format!("{existing} -Cpanic=unwind"));
}

cargo fmt --check is clean and cargo clippy introduces no new warnings. The build::* integration tests all pass locally (cargo test --test all -- --test-threads=1 build:: — 16/16). The default code path (without the flag) is unchanged.

Related: #737 (panic_immediate_abort, distinct from this — that's a size flag).

Make sure these boxes are checked! 📦✅

  • You have the latest version of rustfmt installed
  • You ran cargo fmt on the code base before submitting
  • You reference which issue is being closed in the PR text

Adds a new --panic-unwind option to `wasm-pack build` and `wasm-pack test`
that builds with `-Cpanic=unwind` instead of the default `panic=abort`.

When the flag is set, cargo is invoked via `+nightly` with
`-Z build-std=std,panic_unwind` and `RUSTFLAGS` is augmented with
`-Cpanic=unwind` (preserving any user-provided `RUSTFLAGS`). The nightly
toolchain, `rust-src` component, and nightly `wasm32-unknown-unknown`
target are auto-installed via `rustup` if not already present. The stable
rustc and wasm-target preflight checks are skipped when --panic-unwind is
set, since they are irrelevant for the nightly invocation.

This is a build-tool-level enabler: it produces a wasm artifact compiled
with unwinding semantics. The actual conversion of caught panics into
JavaScript exceptions is the responsibility of the consuming bindings layer
(e.g. wasm-bindgen's catch-unwind support).
@guybedford guybedford merged commit 1e6c1de into wasm-bindgen:master May 13, 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.

1 participant