Skip to content

[pull] main from wasm-bindgen:main#286

Merged
pull[bot] merged 1 commit into
LoadsAForks:mainfrom
wasm-bindgen:main
May 14, 2026
Merged

[pull] main from wasm-bindgen:main#286
pull[bot] merged 1 commit into
LoadsAForks:mainfrom
wasm-bindgen:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 14, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

…5128)

* Enforce unwind safety on #[wasm_bindgen] exports under panic=unwind

Previously the macro wrapped every exported sync function body in
`maybe_catch_unwind(|| { ... })`, but emitted all argument and receiver
`from_abi` conversions *inside* that closure. The closure therefore only
captured the raw ABI integer parameters (which are trivially UnwindSafe),
so the closure-level UnwindSafe bound on `maybe_catch_unwind` was a
no-op for the user's actual types — `&self` / `&mut self` methods on
structs containing `Cell`, `RefCell`, `Mutex`, etc. compiled cleanly,
even though a mid-method panic could leave those types in a torn state
observable on the next call.

Add explicit type-level assertions in the export codegen:

* `&self` / `&mut self` -> `Self: RefUnwindSafe`
* `&T` / `&mut T` args  -> `T: RefUnwindSafe`
* owned arg / `self`     -> `T: UnwindSafe`

These map to two no-op helpers `__rt::assert_ref_unwind_safe` /
`__rt::assert_unwind_safe` which only carry the trait bound under
`cfg(panic = "unwind")`. Stdlib's blanket `&mut T: !UnwindSafe` would
otherwise reject every `&mut self` method unconditionally, so the
asserted property is the *logical* unwind-safety (`RefUnwindSafe` on
the underlying type), separate from the closure's own `UnwindSafe` bound.

Users whose type is genuinely safe to observe after a caught panic can
opt in with `impl RefUnwindSafe for MyType {}` or by wrapping interior-
mutable fields in `std::panic::AssertUnwindSafe`. The in-tree examples
that needed updating:

* `SetterCompute(Rc<Cell<u32>>)` -> field wrapped in `AssertUnwindSafe`
* `WasmBindgenTestContext`       -> manual `impl RefUnwindSafe` (the
  test harness intentionally drives state through interior mutability
  while orchestrating panicking test execution)

Includes a positive runtime test in `tests/wasm/unwind.rs` covering an
exported `&mut self` method that panics mid-mutation on a
`RefUnwindSafe` struct, verifying both that the panic is caught and
that pre-panic mutations remain observable on subsequent calls. The
negative cases are documented inline; they fail at compile time when
uncommented under `panic = "unwind"`.

The check is a complete no-op outside `panic = "unwind"` builds.

The helpers are compile-time bounds, not runtime assertions, and
'assert' overlaps with std's catch_unwind family of *_assert_unwind_safe
wrappers (which mean 'AssertUnwindSafe', i.e. the opposite). 'ensure'
reads as a compile-time requirement without that ambiguity.
@pull pull Bot locked and limited conversation to collaborators May 14, 2026
@pull pull Bot added the ⤵️ pull label May 14, 2026
@pull pull Bot merged commit 8b5d213 into LoadsAForks:main May 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant