@@ -597,34 +597,43 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
597597
598598/// Types which can be safely moved after being pinned.
599599///
600- /// Since Rust itself has no notion of immovable types, and will consider moves to always be safe,
600+ /// Since Rust itself has no notion of immovable types, and considers moves
601+ /// (e.g. through assignment or [`mem::replace`]) to always be safe,
601602/// this trait cannot prevent types from moving by itself.
602603///
603- /// Instead it can be used to prevent moves through the type system,
604- /// by controlling the behavior of pointers wrapped in the [`Pin`] wrapper,
604+ /// Instead it is used to prevent moves through the type system,
605+ /// by controlling the behavior of pointers `P` wrapped in the [`Pin<P> `] wrapper,
605606/// which "pin" the type in place by not allowing it to be moved out of them.
606607/// See the [`pin module`] documentation for more information on pinning.
607608///
608609/// Implementing this trait lifts the restrictions of pinning off a type,
609- /// which then allows it to move out with functions such as [`replace`].
610+ /// which then allows it to move out with functions such as [`mem::replace`].
611+ ///
612+ /// `Unpin` has no consequence at all for non-pinned data. In particular,
613+ /// [`mem::replace`] happily moves `!Unpin` data (it works for any `&mut T`, not
614+ /// just when `T: Unpin`). However, you cannot use
615+ /// [`mem::replace`] on data wrapped inside a [`Pin<P>`] because you cannot get the
616+ /// `&mut T` you need for that, and *that* is what makes this system work.
610617///
611618/// So this, for example, can only be done on types implementing `Unpin`:
612619///
613620/// ```rust
614- /// use std::mem::replace ;
621+ /// use std::mem;
615622/// use std::pin::Pin;
616623///
617624/// let mut string = "this".to_string();
618625/// let mut pinned_string = Pin::new(&mut string);
619626///
620- /// // dereferencing the pointer mutably is only possible because String implements Unpin
621- /// replace(&mut *pinned_string, "other".to_string());
627+ /// // We need a mutable reference to call `mem::replace`.
628+ /// // We can obtain such a reference by (implicitly) invoking `Pin::deref_mut`,
629+ /// // but that is only possible because `String` implements `Unpin`.
630+ /// mem::replace(&mut *pinned_string, "other".to_string());
622631/// ```
623632///
624633/// This trait is automatically implemented for almost every type.
625634///
626- /// [`replace`]: ../../std/mem/fn.replace.html
627- /// [`Pin`]: ../pin/struct.Pin.html
635+ /// [`mem:: replace`]: ../../std/mem/fn.replace.html
636+ /// [`Pin<P> `]: ../pin/struct.Pin.html
628637/// [`pin module`]: ../../std/pin/index.html
629638#[ stable( feature = "pin" , since = "1.33.0" ) ]
630639pub auto trait Unpin { }
0 commit comments