Pin is a reference, so &Pin would be a double-indirection. The expectation is that callers will call borrow on their Pin to reborrow, and hence not lose their original Pin.
There is no *mut, so which pointers are you referring to?
Could you point out which ones? I looked at two and they are both not redundant.
I think auto-deref should take care of that, but not sure; anyway, this is more explicit, so probably better.
I’m also pretty sure auto-deref should make this work:
fn read_ref(self: Pin<SelfReferential>) -> Option<i32> {
// Dereference self_ref if it is non-NULL.
if self.self_ref == ptr::null() {
None
} else {
Some(unsafe { *self.self_ref })
}
}
but this is even less explicit. On the upside, this does look like a more “natural” way of treating a Pinned, as a reference type.
As an afterthought, couldn’t the signature of this function even have self: &SelfReferential? The guarantee is given when you call init, and isn’t required afterwards (if init was never called, the pointer is null anyway). This does highlight the fact that a Pinned is a promise even beyond its lifetime, but maybe makes the example more complicated rather that simpler.
The API changed, so discussing such details of the old API seems moot at this point.
I suppose one could have an invariant that self_ref will only be non-NULL when the item is pinned. That seems sound, but also (as you say) unnecessarily subtle. Good catch!