I'm working with
Pin<Rc<SomeNotUnpinType>>, and I'd like to produce a weak pointer to the underlying allocation. I can imagine two signatures here:
Pin<Rc<T>> -> Pin<rc::Weak<T>>: a pinned weak pointer is not super useful since
Weak<T> is not
Deref, but this still has the effect of keeping the backing allocation alive, and it seems like this form of downgrade should be sound
Pin<Rc<T>> -> rc::Weak<T>: I am less sure that this can be done soundly, seems like it might be possible to exploit it to break the
Pin invariant by upgrading the
Weak, but if it were possible to implement soundly this would be the more useful conversion
So, can either of these downgrades be written soundly? If so, how?
clone() the inner
Rc and then downgrade that?
Edit. No, you can't, because
Pin doesn't give you any access to the pointer type by default.
Which is a good thing in hindsight, because any route that potentially gives you an unpinned
Rc<T> will then let you move the value via
Rc::try_unwrap, which breaks the
Pin guarantee. So, the best you can hope for is something that will give you
The first version is fine, but you probably need to do it unsafely.
Thanks! Would you expect the complementary upgrade operation
Pin<Weak<T>> -> Option<Pin<Rc<T>>> to also be okay?
I see no problem with that.
I don’t think there’s any way of constructing
Pin<Weak<T>> as even
P: Deref, no?
In terms of usable, existing alternatives, there exists https://crates.io/crates/pin-weak
Yeah, I was stymied trying to come up with ways to implement the downgrade even in unsafe code. Perhaps
transmute could do it.
Thanks for the pointer to the pin-weak crate!
Ah, well, that could work - but that seems unnecessarily unsafe.
Also at that point, arguably, you’d be inventing a meaning (and safety invariants) of
Pin<Weak<T>> that may be incompatible (i.e. unsound when combined) with the ones other library authors may come up with, so it seems advisable to avoid doing so and to use a custom type instead, as the
pin-weak crate does, too
Yeah, if the
Pin<Weak<T>> were going to be part of my public API this would be a major concern. In practice I just need "something that acts like a weak pointer to pinned data" for internal use, which the crate seems to provide -- I may just open-code the relevant parts of that implementation.
You can make a
PinWeak<T> struct that wraps a
Weak<T> and provides conversion to/from