Week 14: Unsafe Rust (Advanced)
Overview
Week 14 explores the unsafe side of Rust, teaching you when and how to use unsafe code responsibly. You’ll learn to work with raw pointers, interface with foreign code, and build safe abstractions over unsafe implementations. This knowledge is crucial for systems programming and performance-critical code.
Day 1-2: Understanding Unsafe Fundamentals
Topics
- The
unsafe
keyword and its scope - Unsafe blocks, functions, traits, and impls
- The five unsafe superpowers:
- Dereferencing raw pointers
- Calling unsafe functions
- Implementing unsafe traits
- Accessing/modifying mutable static variables
- Accessing union fields
- Safety invariants and contracts
- Undefined behavior (UB) in Rust
- Common unsafe patterns and anti-patterns
- Tools for detecting UB:
- MIRI (Mid-level IR Interpreter)
- Address Sanitizer (ASAN)
- Valgrind
Resources
- The Rustonomicon - The dark arts of unsafe Rust
- Unsafe Code Guidelines
- Understanding Undefined Behavior
- MIRI Documentation
- What Is Rust’s Unsafe? - Video explanation
Use Cases
- Building safe abstractions over low-level operations
- Performance-critical code where safety checks are too costly
- Implementing data structures with complex invariants
- Interoperating with non-Rust code
- Bypassing compiler limitations in safe code
Day 3-4: Raw Pointers and Memory Manipulation
Topics
- Raw pointer types:
*const T
and*mut T
- Pointer creation and dereferencing
- Pointer arithmetic and alignment
- Null pointers and validity checks
- Converting between references and raw pointers
- Working with uninitialized memory:
- The deprecated
std::mem::uninitialized
- Using
MaybeUninit<T>
- Initialization patterns
- The deprecated
- Byte manipulation with
std::ptr
functions - Memory mapped I/O
- Bit manipulation and direct memory access
- Custom
Drop
implementations with raw pointers
Resources
- Rustonomicon: Raw Pointers
- std::ptr Documentation
- MaybeUninit Documentation
- Memory Alignment in Rust
- Crust of Rust: Raw Pointers by Jon Gjengset
Use Cases
- Custom allocators and memory pools
- Zero-copy data processing
- Hardware device access
- Implementing complex data structures (linked lists, trees)
- Low-level optimization of algorithms
- Working with memory-mapped files
Day 5-7: Safe Abstractions Over Unsafe Code
Topics
- Designing safe APIs that use unsafe internally
- Encapsulating unsafe code
- Proving correctness of unsafe code
- Documentation practices for unsafe code
- Safety invariants:
- Establishing and maintaining invariants
- Documenting invariants
- Testing unsafe code:
- Fuzz testing
- Property-based testing
- MIRI-based testing
- Wrapper types and abstraction techniques
- Case studies of unsafe in standard library:
Vec<T>
implementationString
implementation- Smart pointers
- Auditing unsafe code
- The
unsafe_op_in_unsafe_fn
lint
Resources
- Rustonomicon: Implementing Vec
- Rust Standard Library Source
- Fuzz Testing in Rust
- Testing Strategies for Unsafe Code
- Notes on Type Punning
- Unsafe Guidelines WG
Use Cases
- Building foundational libraries
- Creating data structures with complex internal representations
- Performance optimization of critical paths
- Interfacing with hardware or other languages
- Framework development
- Systems programming
Exercises
- Implement a basic intrusive linked list using raw pointers
- Create a safe abstraction over an unsafe memory buffer
- Build a simple arena allocator using unsafe code
- Implement a custom slice type with different safety guarantees
- Use raw pointers to implement a non-standard collection
- Create a safe wrapper around a C library function
Advanced Challenges
- Implement a thread-safe buffer with lockless operations
- Build a custom smart pointer with specialized memory management
- Implement a memory-efficient B-tree using raw pointers
- Create a zero-copy parser for a binary format
- Design and implement a safe API for memory-mapped I/O operations
Next Steps
After completing Week 14, you’ll understand how to work with unsafe Rust responsibly. Week 15 will build on this foundation to explore advanced design patterns that leverage Rust’s type system for maximum safety and expressiveness.