Unsafe Basics
7 examples - 5 basic, 2 intermediate - for unsafe keyword scope.
Prerequisites
Basic Examples
1. unsafe Block
fn main() {
let v = 42;
let p = &v as *const i32;
let val = unsafe { *p };
println!("{val}");
}- Dereference raw pointer requires
unsafe - Programmer asserts safety
2. unsafe fn
unsafe fn dangerous() {
// caller must uphold invariants
}Calling dangerous() requires unsafe { dangerous(); }.
3. unsafe trait
unsafe trait Trusted {}Implementer promises safety conditions.
4. What Unsafe Allows
- Deref raw pointers
- Call
unsafe fn - Access
static mut - Implement
unsafe trait unionfield access
Borrow checker still applies to safe code.
5. What Unsafe Does NOT Disable
- Ownership and lifetimes on safe references
- Type system (no casting away guards freely)
- Most of Rust still safe by default
Related: Undefined Behavior
Intermediate Examples
6. Safe Abstraction
fn split_at_mut<T>(slice: &mut [T], mid: usize) -> (&mut [T], &mut [T]) {
slice.split_at_mut(mid)
}Std uses unsafe inside - safe API.
7. Document Safety
/// # Safety
/// `ptr` must be valid for reads of one `i32`.
unsafe fn read_int(ptr: *const i32) -> i32 {
*ptr
}Related: Unsafe Rust Best Practices
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.