1919//! obtain a `Box` or reference to pinned data, which implies that you cannot use
2020//! operations such as [`mem::swap`]:
2121//! ```
22+ //! use std::pin::Pin;
2223//! fn swap_pins<T>(x: Pin<&mut T>, y: Pin<&mut T>) {
2324//! // `mem::swap` needs `&mut T`, but we cannot get it.
2425//! // We are stuck, we cannot swap the contents of these references.
3233//! prevents certain *values* (pointed to by pointers wrapped in `Pin`) from being
3334//! moved by making it impossible to call methods like [`mem::swap`] on them.
3435//!
36+ //! [`Pin`] can be used to wrap any pointer type, and as such it interacts with
37+ //! [`Deref`] and [`DerefMut`]. A `Pin<P>` where `P: Deref` should be considered
38+ //! as a "`P`-style pointer" to a pinned `P::Target` -- so, a `Pin<Box<T>>` is
39+ //! an owned pointer to a pinned `T`, and a `Pin<Rc<T>>` is a reference-counted
40+ //! pointer to a pinned `T`.
41+ //! For correctness, [`Pin`] relies on the [`Deref`] and [`DerefMut`] implementations
42+ //! to not move out of their `self` parameter, and to only ever return a pointer
43+ //! to pinned data when they are called on a pinned pointer.
44+ //!
3545//! # `Unpin`
3646//!
3747//! However, these restrictions are usually not necessary. Many types are always freely
114124//! list element will patch the pointers of its predecessor and successor to remove itself
115125//! from the list.
116126//!
117- //! To make this work, it is crucial taht we can actually rely on `drop` being called.
127+ //! To make this work, it is crucial that we can actually rely on `drop` being called.
118128//! And, in fact, this is a guarantee that `Pin` provides.
119129//!
120130//! # `Drop` guarantee
219229//!
220230//! [`Pin`]: struct.Pin.html
221231//! [`Unpin`]: ../../std/marker/trait.Unpin.html
232+ //! [`Deref`]: ../../std/ops/trait.Deref.html
233+ //! [`DerefMut`]: ../../std/ops/trait.DerefMut.html
222234//! [`mem::swap`]: ../../std/mem/fn.swap.html
223235//! [`mem::forget`]: ../../std/mem/fn.forget.html
224236//! [`Box`]: ../../std/boxed/struct.Box.html
@@ -319,16 +331,16 @@ impl<P: Deref> Pin<P> {
319331 /// Construct a new `Pin` around a reference to some data of a type that
320332 /// may or may not implement `Unpin`.
321333 ///
334+ /// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used
335+ /// instead.
336+ ///
322337 /// # Safety
323338 ///
324339 /// This constructor is unsafe because we cannot guarantee that the data
325340 /// pointed to by `pointer` is pinned, meaning that the data will not be moved or
326341 /// its storage invalidated until it gets dropped. If the constructed `Pin<P>` does
327342 /// not guarantee that the data `P` points to is pinned, constructing a
328- /// `Pin<P>` is unsafe. In particular, calling `Pin::new_unchecked`
329- /// on an `&'a mut T` is unsafe because while you are able to pin it for the given
330- /// lifetime `'a`, you have no control over whether it is kept pinned once `'a`
331- /// ends. A value, once pinned, must remain pinned forever (unless its type implements `Unpin`).
343+ /// `Pin<P>` is unsafe. In particular,
332344 ///
333345 /// By using this method, you are making a promise about the `P::Deref` and
334346 /// `P::DerefMut` implementations, if they exist. Most importantly, they
@@ -340,21 +352,38 @@ impl<P: Deref> Pin<P> {
340352 /// must not be possible to obtain a `&mut P::Target` and then
341353 /// move out of that reference (using, for example [`mem::swap`]).
342354 ///
343- /// For example, the following is a *violation* of `Pin`'s safety:
355+ /// For example, calling `Pin::new_unchecked`
356+ /// on an `&'a mut T` is unsafe because while you are able to pin it for the given
357+ /// lifetime `'a`, you have no control over whether it is kept pinned once `'a` ends:
344358 /// ```
345359 /// use std::mem;
346360 /// use std::pin::Pin;
347361 ///
348- /// fn foo <T>(mut a: T, mut b: T) {
362+ /// fn move_pinned_ref <T>(mut a: T, mut b: T) {
349363 /// unsafe { let p = Pin::new_unchecked(&mut a); } // should mean `a` can never move again
350364 /// mem::swap(&mut a, &mut b);
351365 /// // the address of `a` changed to `b`'s stack slot, so `a` got moved even
352366 /// // though we have previously pinned it!
353367 /// }
354368 /// ```
369+ /// A value, once pinned, must remain pinned forever (unless its type implements `Unpin`).
355370 ///
356- /// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used
357- /// instead.
371+ /// Similarily, calling `Pin::new_unchecked` on a `Rc<T>` is unsafe because there could be
372+ /// aliases to the same data that are not subject to the pinning restrictions:
373+ /// ```
374+ /// use std::rc::Rc;
375+ /// use std::pin::Pin;
376+ ///
377+ /// fn move_pinned_rc<T>(mut x: Rc<T>) {
378+ /// let pinned = unsafe { Pin::new_unchecked(x.clone()) };
379+ /// { let p: Pin<&T> = pinned.as_ref(); } // should mean the pointee can never move again
380+ /// drop(pinned);
381+ /// let content = Rc::get_mut(&mut x).unwrap();
382+ /// // Now, if `x` was the only reference, we have a mutable reference to
383+ /// // data that we pinned above, which we could use to move it as we have
384+ /// // seen in the previous example.
385+ /// }
386+ /// ```
358387 ///
359388 /// [`mem::swap`]: ../../std/mem/fn.swap.html
360389 #[ stable( feature = "pin" , since = "1.33.0" ) ]
0 commit comments