# [−][src]Module alloc::pin

🔬 This is a nightly-only experimental API. (`pin` #49150)

Types which pin data to its location in memory

It is sometimes useful to have objects that are guaranteed to not move, in the sense that their placement in memory does not change, and can thus be relied upon.

A prime example of such a scenario would be building self-referencial structs, since moving an object with pointers to itself will invalidate them, which could cause undefined behavior.

In order to prevent objects from moving, they must be pinned, by wrapping the data in pinning pointer types, such as `PinMut` and `PinBox`, which are otherwise equivalent to `& mut` and `Box`, respectively.

First of all, these are pointer types because pinned data mustn't be passed around by value (that would change its location in memory). Secondly, since data can be moved out of `&mut` and `Box` with functions such as `swap`, which causes their contents to swap places in memory, we need dedicated types that prohibit such operations.

However, these restrictions are usually not necessary, so most types implement the `Unpin` auto-trait, which indicates that the type can be moved out safely. Doing so removes the limitations of pinning types, making them the same as their non-pinning counterparts.

# Examples

    #![feature(pin)]

    use std::pin::PinBox;
    use std::marker::Pinned;
    use std::ptr::NonNull;

    // This is a self referencial struct since the slice field points to the data field.
    // We cannot inform the compiler about that with a normal reference,
    // since this pattern cannot be described with the usual borrowing rules.
    // Instead we use a raw pointer, though one which is known to not be null,
    // since we know it's pointing at the string.
    struct Unmovable {
        data: String,
        slice: NonNull<String>,
        _pin: Pinned,
    }

    impl Unmovable {
        // To ensure the data doesn't move when the function returns,
        // we place it in the heap where it will stay for the lifetime of the object,
        // and the only way to access it would be through a pointer to it.
        fn new(data: String) -> PinBox<Self> {
            let res = Unmovable {
                data,
                // we only create the pointer once the data is in place
                // otherwise it will have already moved before we even started
                slice: NonNull::dangling(),
                _pin: Pinned,
            };
            let mut boxed = PinBox::new(res);

            let slice = NonNull::from(&boxed.data);
            // we know this is safe because modifying a field doesn't move the whole struct
            unsafe { PinBox::get_mut(&mut boxed).slice = slice };
            boxed
        }
    }

    let unmoved = Unmovable::new("hello".to_string());
    // The pointer should point to the correct location,
    // so long as the struct hasn't moved.
    // Meanwhile, we are free to move the pointer around.
    let mut still_unmoved = unmoved;
    assert_eq!(still_unmoved.slice, NonNull::from(&still_unmoved.data));

    // Since our type doesn't implement Unpin, this will fail to compile:
    // let new_unmoved = Unmovable::new("world".to_string());
    // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved);

## Structs

PinBox | [ Experimental ] A pinned, heap allocated reference.
PinMut | [ Experimental ] A pinned reference.

## Traits

Unpin | [ Experimental ] Types which can be safely moved after being pinned.

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g. `str,u8` or `String,struct:Vec,test`)