The pin documents are mainly focused on people using Pin with existing pointers, not people who have defined a pointer and create a constructor for a pinned version of their pointer. So when they talk about not moving out of the &mut
, they're talking about those users who want to mutate something inside of a Pin
(for example, someone writing a future combinator by hand).
However, the requirements on constructing pointers are more complicated and not well documented. In general we have not stated them abstractly, but instead just reasoned about the soundness each pointer type we have added a constructor for.
One thing comex has revealed (mainly discussed as "method 3" in the original post) is that with the combination of Pin::new
and CoerceUnsized
, you can construct a pin pointer with an Unpin
target and then coerce it into a Pin
pointer to a target that is not known to implement Unpin
, because your concrete target type gets erased. Therefore, Pin::new
, as a generic safe constructor, does impose restrictions on types which implement CoerceUnsized
(an unstable trait).
Stating abstractly the requirements on pointers to be pinned seems very difficult: the entire idea of using non-generic constructors was that we could reason about each pointer individually even though they are passing through the same Pin
type. I believe that even looking at something like Clone
or DerefMut
alone, you get a tree of ANDs and ORs for the possibly ways you could meet the requirements, and I don't feel confident that would be exhaustive. This is one of the downsides, to me, of adding the unsafe marker traits: I really don't know how we could document them except to explain how each implementation we provide is valid given the specific semantics of that pointer.