Skip to content
TopicTracker
From HackerNewsView original
TranslationTranslation

What is `std:pin:Pin` in Rust?

The article explains Rust's `std::pin::Pin` type, which ensures that a value in memory cannot be moved once pinned. It covers why pinning is necessary for self-referential structs and async state machines, how `Pin` works with `Box` and stack pinning, and the safety guarantees provided by `Unpin` and `!Unpin` traits.

Background

Rust is a systems programming language focused on safety and performance. A core guarantee is that values cannot move in memory while they are borrowed (to prevent dangling pointers). However, certain types (called "self-referential" types) contain pointers to their own memory — if the value moves, those internal pointers become invalid. `std::pin::Pin<P>` is a Rust wrapper type that prevents the underlying value from ever being moved again. It is essential for: - **Async Rust**: The `Future` trait often creates self-referential structs across `await` points; the async runtime must `Pin` the future or move operations would cause undefined behavior. - **Custom smart pointers**: Types like `Box::pin` and `pin!` macro let you create pinned heap/stack allocations. Before Rust 1.0 (2015), self-referential types were simply forbidden. The `Pin` API was stabilized in Rust 1.33 (2019) to safely enable them. Understanding pinning is one of the harder concepts for Rust beginners because it requires reasoning about memory layouts, ownership, and borrow checker rules simultaneously.

Related stories