Skip to content

docs: panic-never (+ question about panic detection in async code) - #7

Open
peter-lyons-kehl wants to merge 1 commit into
OpenDevicePartnership:mainfrom
peter-lyons-kehl:panic-never
Open

peter-lyons-kehl wants to merge 1 commit into
OpenDevicePartnership:mainfrom
peter-lyons-kehl:panic-never

Conversation

@peter-lyons-kehl

Copy link
Copy Markdown

hi Wouter @Wassasin,

  1. I did create a PR: japaric/panic-never#3 from https://github.com/peter-lyons-kehl/panic-never-rs to upstream https://github.com/japaric/panic-never (https://crates.io/crates/panic-never). However, its author has been overloaded, so it may take long. Hence I've mentioned my repo, too.

  2. In addition to this PR, https://tweedegolf.nl/en/blog/242/finding-panics-with-call-graph-analyzer reads "each async block has a panic path, implicitly". That is incorrect. See https://github.com/peter-lyons-kehl/panic-never-rs/tree/master/examples/async_panic_none.

@Wassasin

Wassasin commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Looks good to me!

With regards to point 2: as alluded to in the blog, it is in fact LLVM that optimizes that async block away. (all code is optimized away for that matter) In the MIR and in the non-optimized LLVM-IR passed to LLVM this panic is there. To verify this, run rustc with --emit=mir -C no-prepopulate-passes and read the IR in the target/release/deps folder.

For example:

define internal noundef zeroext i1 @_RNCNvCs8v9h2daBvVj_11panic_never5inner0B3_(ptr noundef nonnull align 1 %_1, ptr noalias noundef align 8 dereferenceable(32) %_task_context) unnamed_addr #1 {
start:
  [..]
  br i1 %4, label %bb5, label %bb1

bb5:                                              ; preds = %bb5, %start
  br i1 false, label %bb5, label %panic

The only reason LLVM is capable of optimizing this panic out is because your executor implementation in the example is not complete: instead of continuously polling a future, it is only polled once.

For real-world executors this panic is not eliminated. (that would look like collection of futures, and a loop which iterates on all of them and switches based on the async block state machine)

CGA is only capable of reasoning about the application within the confines of rustc & the generated MIR.

@peter-lyons-kehl

Copy link
Copy Markdown
Author

Wow. More to learn and investigate (for me).

What exact cargo command can I use to apply --emit=mir -C no-prepopulate-passes (ideally on Linux), please? It seems to conflict/override my .cargo/config.toml which has

[target.'cfg(target_os="linux")']
rustflags = ["-C", "link-arg=-nostartfiles"]

I've tried .cargo/config.toml containing

[target.'cfg(target_os="linux")']
rustflags = ["-C", "link-arg=-nostartfiles", "--emit=mir", "-C", "no-prepopulate-passes"]

Then Google suggested CARGO_ENCODED_RUSTFLAGS="--emit=mir\x1f-C\x1fno-prepopulate-passes" cargo build --release with my original .cargo/config.toml, but that fails, too. Clearly I don't know what I'm doing.

@Wassasin

Wassasin commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

With a recent nightly, you should be able to run the following on your project:

cargo +nightly rustc --example async_panic_none --release -- --emit=mir,llvm-ir -C no-prepopulate-passes

You will find the LLVM-IR at ./target/release/build/panic-never/HASH/out/async_panic_none.ll. (the deps folder was removed in recent cargo)

@peter-lyons-kehl

Copy link
Copy Markdown
Author

Thank you Wouter @Wassasin.

I've removed the mention of async from this PR, and I've force pushed a replacement commit.

@peter-lyons-kehl peter-lyons-kehl changed the title docs: panic-never + examples including detection in async code docs: panic-never (+ question about panic detection in async code) Nov 3, 2026
@peter-lyons-kehl

peter-lyons-kehl commented Nov 6, 2026 •

Copy link
Copy Markdown
Author

Here's how to re-use same code for non-async/blocking and async with duplicate crate. A side fruit: Apply David Tolnay's no_panic to that same code when compiled for non-async/blocking: Emoun/duplicate#60 (comment).

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