25.1 The Unsafe Superset

Safe Rust operates under strict rules (ownership, borrowing, lifetimes, type safety) to prevent undefined behavior (UB). Unsafe Rust provides access to five additional capabilities, sometimes called “unsafe superpowers,” that bypass certain checks:

  1. Dereferencing raw pointers (*const T and *mut T).
  2. Calling unsafe functions (including external functions declared via FFI).
  3. Accessing or modifying static mut variables.
  4. Implementing unsafe traits.
  5. Accessing fields of unions.

Crucially, entering an unsafe context does not disable all of Rust’s safety mechanisms. The borrow checker still operates, ownership rules apply, and type checking is still performed. The unsafe keyword only permits these five specific actions within an unsafe block or function. The responsibility shifts to the programmer to ensure these actions do not violate Rust’s memory safety invariants (e.g., avoiding data races, dangling pointers, invalid pointer arithmetic).

25.1.1 Why Unsafe Rust is Necessary

Despite Rust’s emphasis on safety, the unsafe mechanism is essential for its role as a systems programming language:

  • Hardware Interaction: Direct memory-mapped I/O, register manipulation, or executing specific CPU instructions often requires bypassing safe abstractions.
  • Foreign Function Interface (FFI): Interacting with libraries written in C or other languages involves calling code that Rust’s compiler cannot analyze or verify.
  • Low-Level Data Structures: Implementing certain efficient data structures (e.g., some variants of linked lists, custom allocators, lock-free structures) may require pointer manipulations that are difficult or impossible to express within safe Rust’s constraints.
  • Performance Optimization: In specific, performance-critical sections, manual memory management or pointer operations might offer optimizations beyond what the compiler or safe abstractions provide, although this is less common than the other reasons.

In these situations, the compiler cannot guarantee safety, so the unsafe keyword marks the boundaries where the programmer asserts the code’s correctness regarding Rust’s safety rules.