It depends a bit on your definition of "transfer ownership", e.g. does transferring ownership of a
Box<T> also transfer ownership of the
T? If the answer to that is no, then you cannot ever transfer ownership of a value that has been pinned. The
Pin type exists to make self-referential structs sound. Self-referential structs are normally unsound as all moves are just a memcpy, so any pointers the struct stores into itself would not be updated when the struct is moved, but if you know that the struct is never moved, that's not a problem.
To tie this back to the discussion in this thread, note that a self-referential type would never be usable in safe code without something like
Pin (or heap allocation), because the soundness relies on the owner of the object making a promise to never move the object. It is possible to define a
pin! macro that makes use of variable shadowing to ensure that the value can never be moved again, allowing safe code to pin something to the stack.
Pin is actually an example of library code that gives the compiler the ability to verify something, that the compiler was not able to verify previously. Now that the
Pin api exists, a user can, in safe code, pin some value, and have the compiler verify that the value does in fact not move later. Once the value is pinned, the user can obtain a
Pin<&mut T> to that value, and by passing a pinned reference to other functions, those other functions know that the argument is definitely pinned, and can rely on that guarantee in unsafe code.
As an example, the standard library mutex stores the value in an heap allocation, which is necessary due to some OS apis taking pointers directly to the mutex. If the mutex object was moved, that would invalidate those pointers. Now that
Pin exists, it would be possible to rewrite mutex to instead take a pinned reference when locking the mutex, and by doing this, the user can promise that they wont move the mutex object, and it would be perfectly fine to give the OS pointers into objects owned by the caller, instead of using a heap allocation to ensure the pointers remain valid.