Coroutines, Self-Referential Structs, and Pinning 234 Pinning in theory Pinning is a part of Rust's standard library and consists of two parts: the type, Pin, and the marker-trait, Unpin. Pinning is only a language construct. There is no special kind of location or memory that you move values to so they get pinned. There is no syscall to ask the operating system to ensure a value stays the same place in memory. It's only a part of the type system that's designed to prevent us from being able to move a value. Pin does not remove the need for unsafe -it just gives the user of unsafe a guarantee that the value has a stable location in memory, so long as the user that pinned the value only uses safe Rust. This allows us to write self-referential types that are safe. It makes sure that all operations that can lead to problems must use unsafe. Back to our coroutine example, if we were to move the struct, we' d have to write unsafe Rust. That is how Rust upholds its safety guarantee. If you somehow know that the future you created never takes a self-reference, you could choose to move it using unsafe, but the blame now falls on you if you get it wrong. Before we dive a bit deeper into pinning, we need to define several terms that we'll need going forward. Definitions Here are the definitions we must understand: Pin<T> is the type it's all about. Y ou'll find this as a part of Rust's standard library under the std::pin module. Pin wrap types that implement the Deref trait, which in practical terms means that it wraps references and smart pointers. Unpin is a marker trait. If a type implements Unpin, pinning will have no effect on that type. Y ou read that right-no effect. The type will still be wrapped in Pin but you can simply take it out again. The impressive thing is that almost everything implements Unpin by default, and if you manually want to mark a type as !Unpin, you have to add a marker trait called Phantom Pinned to your type. Having a type, T, implement !Unpin is the only way for something such as Pin<&mut T> to have any effect. Pinning a type that's !Unpin will guarantee that the value remains at the same location in memory until it gets dropped, so long as you stay in safe Rust. Pin projections are helper methods on a type that's pinned. The syntax often gets a little weird since they're only valid on pinned instances of self. For example, they often look like fn foo(self: Pin<&mut self>).