owned-pin 0.2.0

A wrapper that both owns and pins data in memory
Documentation

Owned Pin

This crate deals with data that is owned by some entity but (maybe) immovable in memory. It is inspired by R-value references in C++.

See the documentation for more information.

Examples

With Pin<P> only, we cannot guarantee the move semantics of the value.

use core::pin::{Pin, pin};
use core::marker::PhantomPinned;

fn try_to_take_the_ownership_of<T>(pinned: Pin<&mut T>) {}

let mut value = pin!(PhantomPinned);
// The caller can reborrow the value...
try_to_take_the_ownership_of(value.as_mut());
// ... so the same pinned data can be used twice,
// thus unable to guarantee the move semantics.
try_to_take_the_ownership_of(value.as_mut());

But the [OPin<T, P>] wrapper, which both "own" and "pin" the data in the memory, enables the example above to work as desired:

use owned_pin::{OPin, opin};
use core::marker::PhantomPinned;

fn take_the_ownership_of<T>(owned_and_pinned: OPin<T>) {}

let value = opin!(PhantomPinned);
// The `as_mut` method of `OPin` actually returns `Pin<&mut T>`...
take_the_ownership_of(value);
// ... so the value itself cannot be used again.
// The line below causes rustc to emit `E0382`.
// take_the_ownership_of(value);

With data that implements Unpin, we can even move it out from the wrapper safe and sound:

use owned_pin::{opin, unpin};

// Pins the value onto the stack.
let pinned = opin!(String::from("Hello!"));
// Retrieves back the data because `String` is `Unpin`.
let string = unpin(pinned);