Skip to content

Complex EH flow miscompiled on wasm #153948

@purplesyringa

Description

@purplesyringa

Code

I tried this code, built under --target wasm32-unknown-emscripten --release (try setting CGUs to 1 if it doesn't reproduce on your end):

fn main() {
    struct Dropper;
    impl Drop for Dropper {
        fn drop(&mut self) {
            let _ = std::panic::catch_unwind(|| std::panic::resume_unwind(Box::new(())));
        }
    }

    let _ = std::panic::catch_unwind(|| {
        let _dropper = Dropper;
        std::panic::resume_unwind(Box::new(()));
    });
}

I expected to see this happen: the program completes successfully.

Instead, this happened:

thread 'main' (1) panicked at /rustc/1e2183119f0ee19cc26df899e26b04ad0de3475d/library/core/src/panicking.rs:233:5:
panic in a destructor during cleanup
thread caused non-unwinding panic. aborting.
Aborted()
wasm://wasm/rust_test.wasm-00b53692:1


RuntimeError: unreachable
    at rust_test.wasm.__trap (wasm://wasm/rust_test.wasm-00b53692:wasm-function[290]:0xd203)
    at abort (/home/purplesyringa/rust-test/target/wasm32-unknown-emscripten/debug/rust-test.js:383:5)
    at __abort_js (/home/purplesyringa/rust-test/target/wasm32-unknown-emscripten/debug/rust-test.js:676:7)
    at rust_test.wasm.abort (wasm://wasm/rust_test.wasm-00b53692:wasm-function[244]:0xa253)
    at rust_test.wasm.std::sys::pal::unix::abort_internal (wasm://wasm/rust_test.wasm-00b53692:wasm-function[116]:0x4973)
    at rust_test.wasm.std::process::abort (wasm://wasm/rust_test.wasm-00b53692:wasm-function[59]:0x1983)
    at rust_test.wasm.std::panicking::panic_with_hook (wasm://wasm/rust_test.wasm-00b53692:wasm-function[69]:0x2297)
    at rust_test.wasm.std::panicking::panic_handler::{closure#0} (wasm://wasm/rust_test.wasm-00b53692:wasm-function[63]:0x1a6a)
    at rust_test.wasm.std::sys::backtrace::__rust_end_short_backtrace::<std::panicking::panic_handler::{closure#0}, !> (wasm://wasm/rust_test.wasm-00b53692:wasm-function[62]:0x19b6)
    at rust_test.wasm.__rustc::rust_begin_unwind (wasm://wasm/rust_test.wasm-00b53692:wasm-function[89]:0x3514)

Version it worked on

It most recently worked on: Rust 1.94.0

Version with regression

rustc --version --verbose:

rustc 1.95.0-beta.3 (94a8e826a 2026-03-08)
binary: rustc
commit-hash: 94a8e826a57fdc895506a0e9329246ae914740d5
commit-date: 2026-03-08
host: x86_64-unknown-linux-gnu
release: 1.95.0-beta.3
LLVM version: 22.1.0

Seems to coincide with an LLVM update (21 -> 22), from a quick look at the produced WASM code it increased in size and started using the delegate opcode, probably something fishy there. Haven't had time to debug it further yet.

@rustbot label +T-compiler +O-wasm +O-emscripten +A-panic +I-miscompile +A-LLVM +regression-from-stable-to-beta -regression-untriaged

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-panicArea: Panicking machineryC-bugCategory: This is a bug.I-miscompileIssue: Correct Rust code lowers to incorrect machine codeO-emscriptenTarget: 50% off wasm32-unknown-musl. the savings come out of stdio.h, but hey, you get SDL!O-wasmTarget: WASM (WebAssembly), http://webassembly.org/P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-betaPerformance or correctness regression from stable to beta.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions