← ClaudeAtlas

rust-pinninglisted

Understand and correctly use Pin<Ptr> — what pinning actually prevents, Unpin vs !Unpin, PhantomPinned, and the specific ways Drop can accidentally move a pinned value. Use when hand-implementing Future, building a self-referential struct, seeing "cannot be unpinned" or an unsatisfied `Unpin` trait bound compile error, or implementing Drop for a !Unpin type.
takurot/rust-skills-comprehensive · ★ 0 · Code & Development · score 71
Install: claude install-skill takurot/rust-skills-comprehensive
# Rust Pinning `Pin` trips up even experienced Rust users. This is deliberately a standalone skill (not folded into `rust-async`, which links here) because the mechanics are general — they matter any time a type must never move in memory, not only inside `async fn`. ## What a "move" actually is in Rust Every move — even for a type that doesn't implement `Copy` — is a **bitwise memcpy** to a new location, with the compiler considering the old location's contents "no longer valid" but doing nothing to the actual bytes: ```rust let a = DynamicBuffer::default(); let mut b = a; // compiles to an actual memcpy of DynamicBuffer's bytes from `a`'s // stack slot to `b`'s — verifiable in the generated LLVM IR/assembly ``` The implication that matters for pinning: **a value's memory address is never stable** by default. Anything that stores a pointer to *its own* other field (a self-reference) breaks the instant the containing value is moved — the pointer now points at the old, stale location. ## What pinning is (and isn't) **Pinning prevents a value from being moved**, once it's behind `Pin<Ptr>`, for as long as it doesn't implement `Unpin`. This matters for exactly one reason: it makes self-referential structs (a struct holding a pointer into its own other field) sound to construct, which is otherwise impossible in safe Rust — the compiler generates a self-referential struct automatically whenever an `async fn`/block holds a reference across an `.await` poin