Unsafe Rust
unsafe is an escape hatch that tells the compiler you’ve manually verified code the borrow checker cannot.
Why does it exist?
The compiler prefers rejecting a correct program over accepting an incorrect one. Sometimes you genuinely need low-level tricks (FFI, memory-mapped I/O, type punning) that the compiler can’t verify. Get it wrong and you get every bug Rust tries to avoid: UB, races, segfaults, leaks.
Inside an unsafe block you can do five things normally forbidden:
- Call an unsafe function/method
- Access or modify a mutable static variable
- Implement an unsafe trait
- Access the fields of a
union - Dereference a raw pointer
unsafeis narrower than people thinkThe borrow checker still runs inside
unsafeblocks. You don’t get to ignore the rules, you just get five extra operations.
Conventions:
- Keep
unsafeblocks small and document their safety conditions - An unsafe function says “caller is responsible for safety conditions”; calling one requires its own
unsafe { ... }wrapper - Raw pointers can be created anywhere but dereferencing requires
unsafe - Common uses: FFI into C, writing to specific memory addresses (memory-mapped I/O), unions
unsafeis not a rubber stampWrapping a call in
unsafe { ... }makes the compiler quiet but doesn’t prove correctness. A thorough reviewer still asks whether you read the function’s safety docs.