Does pinning T imply all U's in T are also pinned?

If I have a Pin<Box<P>>, and I uphold the pinning contract, does that necessarily imply that subset structures within the pointee of P also are pinned? Or, will I have to pin those to memory as well? The reason why I ask is that I need a subset struct to have a pointer to another subset structure

Let's also assume that the std::mem::size_of::<Subset>() == const for all subset items within the pointee of P

No, pinning only pins the Target, not any of the fields.

I.e.

Given

struct NewType<T>(pub T);

Pin<&mut NewType<Foo>> does not pin Foo unless NewType explicitly makes that guarantee.

1 Like

Pinning a value does allow that value to consider its fields pinned, as long as it does not violate the pinning guarantees in some way (such as by moving them during Drop). This is known as "Pin Projection" and has some documentation in the stdlib. There is a very helpful library pin-project which provides a macro to safely perform pin projection on a type.

Note that only the pinned value gets to make the choice on whether its fields are pinned. If you are using some type and have pinned it you must use a method provided by that type (like Option::as_pin_mut) to project the pin to its fields. It may have chosen to not project the pinning guarantee to its fields, in which case you creating a pinned reference to its fields externally would be unsound.

1 Like

Feel free to look at this post and the discussion that follows: When is it safe to move a member value out of a pinned future?

Similar to ::pin-project there is the ::easy-pin crate, which is still WIP as I want to make it not require any unsafe while guarding against bad usages, so that users will get compiler errors instead of unsound code (e.g., prevent a user offering a pin-projection to a generic field from implementing Unpin on the struct without guarding that the type of that field is also Unpin)

  • (There are still no docs given the alpha stage, but you can have a look at the examples)

In particular, it offers a PinSensitive wrapper, which I find more useful than stdlib's PhantomPinned

1 Like