In Rust, there are two main methods to indicate something has gone wrong in a program: A function returning a (potentially custom-defined) Err(E)
, from the Result<T, E>
type and a panic!
.
Panicking is not an alternative for exceptions, which are commonly found in other languages. In Rust, a panic is to indicate something has gone seriously wrong and that it cannot continue. Here is an example from the Vec
source for push
:
pub fn push(&mut self, value: T) {
// This will panic or abort if we would allocate > isize::MAX bytes
// or if the length increment would overflow for zero-sized types.
if self.len == self.buf.cap() {
self.buf.double();
}
...
}
If we run out of memory, there's not much else Rust can do, so it will either panic (the default behavior) or abort (which needs to be set with a compilation flag).
Panicking will unwind the stack, running destructors and ensuring that memory is cleaned up. Abort does not do this, and relies on the OS to clean it up properly.
Try to run the following program both normally, and with
[profile.dev]
panic = "abort"
in your Cargo.toml
.
// main.rs
struct Foo(i32);
impl Drop for Foo {
fn drop(&mut self) {
println!("Dropping {:?}!", self.0);
}
}
fn main() {
let foo = Foo(1);
panic!("Aaaaaaahhhhh!");
}