On this page

Date
2026-06-02
Read
2 min
Topic
rust
rust · async

Pin and self-referential structs in Rust

2026-06-022 min readrust

Pin is the type that makes people bounce off async Rust. It's not ceremony for its own sake — it's how the language keeps self-referential structs (most async state machines) from moving in memory while pointers inside them still point inward.

The problem

self-ref.rs
1struct Bad {2    slice: [u8; 4],3    ptr: *const u8, // would point into slice if we built it wrong4}

If Bad moved, ptr would dangle. Async futures often embed pointers into their own stack frame — same issue, bigger scale.

Pin breaks the move

Pin<P> promises not to move the pointee (unless Unpin). The compiler then allows safe APIs that rely on a stable address.

🦀
Ferris' hot tip

Most types are Unpin — ordinary structs move freely. Pin matters for generated future state machines and manual self-referential code. You'll feel it in async traits and some stream adapters long before you write Pin yourself.

Practical guidance

When you need Pin
owns: stable address
async state machinesintrusive lists / self-referential buffers
If you're not building those, you probably import Pin because a trait requires it.
When you don't
owns: everyday Rust
`Box` + no internal pointers into selfdata moved by value only
Don't Pin everything "just in case."

For the concurrency story that makes all this matter, start with lock-free part one.

Comments
Loading comments…