panic in a no-unwind function leads to not dropping local variables (original) (raw)

Raised by @CAD97:

I actually find the current behavior of #![feature(c_unwind)] unwinding in extern "C" somewhat strange. Specifically, any unwinding edges within the extern "C" fn get sent to core::panicking::panic_cannot_unwind, meaning that the unwind happens up to the extern "C" fn, but any locals in said function don't get dropped. I would personally not expect wrapping the body of an extern "C" function in an inner extern "Rust" function to change behavior, but it does.

Reproducing example:

#![feature(c_unwind)]

struct Noise; impl Drop for Noise { fn drop(&mut self) { eprintln!("Noisy Drop"); } }

extern "C" fn test() { let _val = Noise; panic!("heyho"); }

fn main() { test(); }

I would expect "Noisy Drop" to be printed, but it is not.

IMO it'd make most sense to guarantee that with panic=unwind, this destructor is still called. @nbdd0121 however said they don't want to guarantee this.

What is the motivation for leaving this unspecified? The current behavior is quite surprising. If I understand @CAD97 correctly, we currently could make "Noisy Drop" be executed by tweaking the MIR we generate.

Tracking: