Rust Panic
A panic is Rust's emergency brake for a failure that should never happen. A panic is not for expected failures.
panic! stops on purpose
panic! pulls the emergency brake for the current thread. Rust prints your message together with the file and line where it happened, then the thread ends. Run this and the report ends with the line: age cannot be negative: -3
let age = -3;
if age < 0 {
panic!("age cannot be negative: {age}");
}todo! marks a body that is not written yet
Call this function before writing it. The program panics. The report says: not yet implemented: settings loading is not written yet. Older code spells the same idea unimplemented!()
fn load_settings() -> String {
todo!("settings loading is not written yet")
}expect says why, in your words
unwrap() panics with a plain note. expect() panics with your message instead, so the report explains itself. This one stops the program, reporting: the settings file must load first
let file: Option<&str> = None;
let name = file.expect("the settings file must load first");The calm twin: get instead of indexing
Indexing scores[5] directly would panic with "index out of bounds". get asks politely and hands back an Option, so a bad index is just a case to handle:
let scores = [10, 20];
match scores.get(5) {
Some(v) => println!("score = {v}"),
None => println!("no score there"),
}Example
fn main() {
let scores = [10, 20];
let index = 5;
match scores.get(index) {
Some(v) => println!("score = {}", v),
None => println!("no score at index {}, handled without panicking", index),
}
println!("indexing scores[5] directly would have panicked");
}Key points
- unreachable!() marks code that should never run
- Set RUST_BACKTRACE=1 to see the chain of calls that led to a panic
- Only the panicking thread stops.
- The rest of the program stays consistent.
- A project can choose panic = 'abort' under [profile.release] in Cargo.toml.
- The program then stops at once with no unwinding.
- This makes the binary smaller.
- The operating system reclaims the memory.
In this example, scores has only two items, at positions 0 and 1. Asking for scores[5] directly would panic with "index out of bounds". Instead, the code uses get(5), which returns an Option. The match handles both sides: Some prints the score, and None prints a friendly message and the program keeps running. The last line simply reminds you what the direct index would have done.
Note
A missing file is not a bug — return a Result for it.
Save panic for broken promises inside your own code, like indexing with an impossible position.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
A program starts and its config file is missing. What fits best?