In this lesson, you will learn how the Unpin trait acts as a "safety switch" that tells the Rust compiler whether a type can be safely moved even when it is wrapped in a Pin pointer.
The Problem with Moving
In Rust, most types are "movable" by default. If you move a struct, the compiler just performs a memcpy to the new location. However, some types are self-referential (a field contains a pointer to another field within the same struct). If you move such a struct, that internal pointer becomes invalid, leading to instant memory unsafety. Pin exists to stop these types from being moved.
The Unpin Trait
The Unpin trait is a marker trait—it contains no methods. It is an auto-trait, meaning the compiler automatically implements it for almost every type. If a type implements Unpin, it means: "Even if this is wrapped in a Pin pointer, it is safe to move."
Most types, like i32, String, or standard structs, are Unpin. They don't have self-referential requirements, so Pin<Box<i32>> behaves just like a regular Box<i32>.
When is a type NOT Unpin?
A type only loses its Unpin status if it is explicitly designed to be self-referential (such as types generated by async blocks or certain state machines).
Consider this comparison:
use std::marker::PhantomPinned;
// This type is NOT Unpin because of PhantomPinned
struct SelfReferential {
_marker: PhantomPinned,
}
fn process_data<T>(data: Pin<&mut T>)
where T: Unpin
{
// Because of the Unpin bound, we know it's safe
// to move or access the value directly here.
}
If you try to pass a non-Unpin type into a function that requires Unpin, the compiler will stop you. This protects you from accidentally moving a self-referential structure that would break its internal pointers.
In short, you don't usually need to implement Unpin yourself. Instead, you rely on it as a trait bound to tell your generic code: "I am okay working with this pinned type because it doesn't have unstable internal pointers."
Key Takeaway: The Unpin trait is the mechanism that signals a type is safe to move, even when pinned; almost all types are Unpin by default, protecting you from memory unsafety only when you specifically opt into self-referential structures.