#rc #pin #arc #weak

pin-weak

Small wrapper around an equivalent of Pin<Weak<T>>

2 stable releases

1.1.0 Nov 29, 2021
1.0.0 Aug 3, 2020

#101 in Memory management

Download history 3809/week @ 2023-11-20 3891/week @ 2023-11-27 3154/week @ 2023-12-04 3407/week @ 2023-12-11 2857/week @ 2023-12-18 2196/week @ 2023-12-25 3280/week @ 2024-01-01 4505/week @ 2024-01-08 4179/week @ 2024-01-15 4473/week @ 2024-01-22 4531/week @ 2024-01-29 4408/week @ 2024-02-05 5029/week @ 2024-02-12 5832/week @ 2024-02-19 4341/week @ 2024-02-26 3972/week @ 2024-03-04

19,587 downloads per month
Used in 40 crates (12 directly)

MIT license

10KB
96 lines

Crates.io Documentation

pin-weak

This create provides weak pointers for Pin<std::rc::Rc<T>> and Pin<std::rc::Arc<T>>

Motivation

Pin<std::rc::Rc<T>> and Pin<std::rc::Arc<T>> cannot be converted safely to their Weak<T> equivalent if T does not implement Unpin. That's because it would otherwise be possible to do something like this:

struct SomeStruct(PhantomPinned);
let pinned = Rc::pin(SomeStruct(PhantomPinned));

// This is unsafe ...
let weak = unsafe {
    Rc::downgrade(&Pin::into_inner_unchecked(pinned.clone()))
};

// ... because otherwise it would be possible to move the content of pinned:
let mut unpinned_rc = weak.upgrade().unwrap();
std::mem::drop((pinned, weak));
// unpinned_rc is now the only reference so this will work:
let x = std::mem::replace(
    Rc::get_mut(&mut unpinned_rc).unwrap(),
    SomeStruct(PhantomPinned),
);

In that example, x is the original SomeStruct which we moved in memory, that is undefined behavior, do not do that at home.

PinWeak

This crate simply provide a rc::PinWeak and sync::PinWeak which allow to get weak pointer from Pin<std::rc::Rc> and Pin<srd::sync::Arc>.

This is safe because you can one can only get back a Pin out of it when trying to upgrade the weak pointer.

PinWeak can be created using the PinWeak downgrade function.

Example

use pin_weak::rc::*;
struct SomeStruct(PhantomPinned, usize);
let pinned = Rc::pin(SomeStruct(PhantomPinned, 42));
let weak = PinWeak::downgrade(pinned.clone());
assert_eq!(weak.upgrade().unwrap().1, 42);
std::mem::drop(pinned);
assert!(weak.upgrade().is_none());

License

MIT

No runtime deps

Features