Crates.io | pin-weak |
lib.rs | pin-weak |
version | 1.1.0 |
source | src |
created_at | 2020-08-03 07:13:33.14351 |
updated_at | 2021-11-29 12:49:24.744318 |
description | Small wrapper around an equivalent of Pin |
homepage | |
repository | https://github.com/sixtyfpsui/pin-weak |
max_upload_size | |
id | 272423 |
size | 12,290 |
This create provides weak pointers for Pin<std::rc::Rc<T>>
and Pin<std::rc::Arc<T>>
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.
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());
MIT