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?
Can you 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 Pin<Weak<T>>.
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.