owned-pin

Crates.ioowned-pin
lib.rsowned-pin
version1.3.3
sourcesrc
created_at2023-11-30 05:05:17.19236
updated_at2023-12-02 08:28:43.323706
descriptionA wrapper that both owns and pins data in memory
homepage
repositoryhttps://github.com/js2xxx/owned-pin
max_upload_size
id1053869
size65,423
Js2xxx (js2xxx)

documentation

README

Owned Pin

Cargo Documentation License

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());

In practice, this is because there is no such smart pointer that owns data by holding a unique reference to some other location on the stack.

Thus, we introduce the OnStack<T> smart pointer and an alias of OPin<T> = Pin<OnStack<T>>, which both "own" and "pin" the data on the stack, enabling 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 a `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: String = unpin(pinned);

License

MIT OR Apache-2.0

Commit count: 34

cargo fmt