panic! and unwinding for unrecoverable errors

Marcus Chen Jan 2026
1 tab
fn divide(a: i32, b: i32) -> i32 {
    if b == 0 {
        panic!("division by zero");
    }
    a / b
}

fn main() {
    let result = divide(10, 2);
    println!("Result: {}", result);
    // divide(10, 0); // This would panic
}
1 file · rust Explain with highlit

Rust panics are for bugs, not expected errors. When code panics (via panic!, unwrap(), expect(), or assertion failure), the thread unwinds by default, running destructors. I use panic! for invariant violations or \"this should never happen\" cases. For production, set panic = 'abort' in Cargo.toml to skip unwinding and reduce binary size. Panics can be caught with std::panic::catch_unwind, but this is rare; Rust prefers Result for recoverable errors. I reserve panics for programming errors and use Result for runtime errors. The key is intentionality: panics mean \"the program state is corrupt,\" while Result means \"this operation might fail normally.\"