Let no one think of me that I am humble or weak or passive; Let them understand I am of a different kind: dangerous to my enemies, loyal to my friends. To such a life glory belongs.
The secret joy of systems programming is that, underneath every single safe language and carefully designed abstraction is a swirling maelstrom of wildly unsafe machine language and bit-fiddling. You can write that in Rust, too.
The language we’ve presented up to this point in the book ensures your programs are free of memory errors and data races entirely automatically, through types, lifetimes, bounds checks, and so on. But this sort of automated reasoning has its limits; there are many valuable techniques that Rust cannot recognize as safe.
Unsafe code lets you tell Rust, “In this case, just trust me.” By marking off a block or function as unsafe, you acquire the ability to call
unsafe functions in the standard library, dereference unsafe pointers, and call functions written in other languages like C and C++, among other powers. All of Rust’s usual safety checks still apply: type checks, lifetime checks, and bounds checks on indices all occur normally. Unsafe code just enables a small set of additional features.
This ability to step outside the boundaries of safe Rust is what makes it possible to implement many of Rust’s most fundamental features in Rust itself, as is commonly done in C and C++ systems. Unsafe code is what allows the
Vec type to manage ...