FABRKNT
Reading the Stack — Bridge to Intermediate
Rust for source-reading
Lesson 8 of 10·CONTENT10 min20 XP

Treat this page as a workbench, not a blog post. The goal is to extract a reusable mental model from the source and carry it into the rest of the Fabrknt stack.

Course
Reading the Stack — Bridge to Intermediate
Lesson role
CONTENT
Sequence
8 / 10

Lesson 7 — unsafe Rust

Question

unsafe blocks temporarily remove Rust's safety guarantees. Normally you avoid them. But Reth / Revm hotpaths use unsafe for performance. When, why is it safe, and how do you read it?

Principle (minimum model)

  • Five things unsafe enables. (1) Dereferencing a raw pointer. (2) Mutating a static. (3) Calling an unsafe fn. (4) Implementing an unsafe trait. (5) Accessing union fields.
  • What Rust's safety guarantees are. Memory safety + no data races + no undefined behaviour, all enforced at compile time via ownership / borrowing / lifetimes. unsafe removes that.
  • The contract pattern. Inside an unsafe block, encode "an invariant I checked myself" and trust the compiler to honour it. Break the contract → instant UB.
  • unwrap_unchecked(). The unsafe variant of Option::unwrap. UB if None, but skips the runtime check. Hotpath speedup when you can prove Some ahead of time.
  • Revm's popn_top! macro. Guards with if stack.len() < N { return Err } first, then unwrap_unchecked to skip the runtime Some check. The guard proves the invariant.
  • unsafe fn is the advertised version. The function itself is unsafe — the caller is responsible for the contract. pub unsafe fn puts the contract in the doc comment.
  • Soundness. Unsafe code is sound when it cannot cause UB on any input. Violating soundness = anyone can hit UB with valid input → a real bug.
  • How to read it. When you see unsafe, ask "why is this needed?" and "what invariant is assumed?" Read the surrounding comments / docs — they explain the contract.

Worked example + steps

unsafe Rust

One of two areas where the standard Rust book is thin, and where Revm's interpreter goes deep. This lesson gives you enough vocabulary to read Revm's hot path without flinching at unsafe { ... } blocks. (The other area — macro_rules! — is the next lesson; together they're what you need to read popn_top! and friends.)

What unsafe actually allows

Rust's safety guarantees (no data races, no use-after-free, no out-of-bounds access) are enforced by the compiler — but only over safe Rust. There are five things only unsafe code can do:

  1. Dereference a raw pointer (*const T or *mut T)
  2. Call an unsafe fn (a function the compiler can't verify)
  3. Access or modify a mutable static variable
  4. Implement an unsafe trait (like Send or Sync manually)
  5. Access fields of a union

That's the entire list. Crucially, unsafe doesn't turn off Rust's borrow checker for your local variables, doesn't allow null pointer derefs automatically, and doesn't let you skip type-checking.

The contract — what unsafe does

unsafe is a promise from you to the compiler: "I have manually verified that this code maintains Rust's safety invariants. You can trust me."

If the promise is wrong, you get undefined behavior (UB) — and UB is catastrophic. Once UB happens, the entire program is in an inconsistent state. The compiler may have optimized assuming UB doesn't happen, so the actual runtime behavior can be anything: crashes, wrong results, security holes, plausible-looking-but-wrong output.

There is no "small UB." A program with UB is wrong, full stop.

Why Revm uses unsafe on the hot path

Revm's popn_top! macro from Intermediate lesson 1 contains:

let ([$( $x ),*], $top) = unsafe {
    $crate::interpreter_types::StackTr::popn_top(&mut $interpreter.stack)
        .unwrap_unchecked()
};

The function being called returns Option<...>. unwrap_unchecked() is the unsafe version of unwrap() — it skips the runtime "is this Some?" check.

Why is this safe here? Because the immediately preceding code is:

if $interpreter.stack.len() < (1 + $crate::_count!($($x)*)) {
    return Err(...);
}

So at the moment of unwrap_unchecked(), the stack length is provably sufficient. The author has verified by inspection that popn_top will return Some. Calling .unwrap() would do a redundant runtime check; .unwrap_unchecked() skips it.

The cost saved: one branch per opcode execution. On the hot path of an interpreter that runs billions of times, that's measurable.

The unsafe discipline in Revm/Reth

Idiomatic unsafe use looks like this:

// Comment block explaining the safety invariant
// SAFETY: We just checked stack.len() >= N+1 above, so popn_top
// is guaranteed to return Some.
let result = unsafe { popn_top.unwrap_unchecked() };

Every unsafe block in well-written Rust has a // SAFETY: comment describing why the unsafe is sound. Reviewers look for these; their absence is a code smell.

unsafe fn vs unsafe { ... }

Two related but different concepts:

FormMeaning
unsafe { ... } block"I'm doing one of the 5 unsafe things, and I've verified the invariants"
unsafe fn foo(...)"Calling this function requires unsafe — the caller must verify invariants"

unwrap_unchecked() is an unsafe fn. To call it, you wrap the call site in unsafe { ... }. That's the contract: the function declares "I have a precondition," the caller declares "I've checked it."

What you do NOT need to know yet

  • Manual implementation of Send / Sync (Reth doesn't really do this)
  • Inline assembly (almost never)
  • FFI to C (only relevant for jemalloc, which is one global setting)

For reading Revm/Reth source, the patterns above (manual safety verification + unwrap_unchecked after a check) are 95% of what you'll see.

What you should walk away with

  • unsafe allows 5 specific things; it's a contract with the compiler, not a license
  • unwrap_unchecked() + a preceding length/state check is the canonical Revm pattern for skipping redundant runtime checks on the hot path
  • The // SAFETY: comment discipline — every unsafe block in well-written Rust documents the invariant that justifies it

The next lesson covers macro_rules!, the other half of what you need to read Revm's interpreter source.

Summary (3 lines)

  • unsafe enables five operations while removing Rust's safety guarantees. The contract pattern encodes a manually-verified invariant for the compiler.
  • Revm's popn_top! uses unwrap_unchecked after a guard proves the invariant — the guard is the contract.
  • Read unsafe by asking "why" and "what invariant" — the comments explain. unsafe is a last resort; soundness is the bar. Next lesson: macro_rules! basics.