|
7 | 7 | //! since moving an object with pointers to itself will invalidate them,
|
8 | 8 | //! which could cause undefined behavior.
|
9 | 9 | //!
|
10 |
| -//! In order to prevent objects from moving, they must be pinned |
11 |
| -//! by wrapping a pointer to the data in the [`Pin`] type. A pointer wrapped |
12 |
| -//! in a `Pin` is otherwise equivalent to its normal version, e.g., `Pin<Box<T>>` |
13 |
| -//! and `Box<T>` work the same way except that the first is pinning the value |
14 |
| -//! of `T` in place. |
| 10 | +//! By default, all types in Rust are movable. Rust allows passing all types by-value, |
| 11 | +//! and common smart-pointer types such as `Box`, `Rc`, and `&mut` allow replacing and |
| 12 | +//! moving the values they contain. In order to prevent objects from moving, they must |
| 13 | +//! be pinned by wrapping a pointer to the data in the [`Pin`] type. |
| 14 | +//! Doing this prohibits moving the value behind the pointer. |
| 15 | +//! For example, `Pin<Box<T>>` functions much like a regular `Box<T>`, |
| 16 | +//! but doesn't allow moving `T`. The pointer value itself (the `Box`) can still be moved, |
| 17 | +//! but the value behind it cannot. |
15 | 18 | //!
|
16 |
| -//! First of all, these are pointer types because pinned data mustn't be passed around by value |
17 |
| -//! (that would change its location in memory). |
18 |
| -//! Secondly, since data can be moved out of `&mut` and `Box` with functions such as [`swap`], |
19 |
| -//! which causes their contents to swap places in memory, |
20 |
| -//! we need dedicated types that prohibit such operations. |
| 19 | +//! Since data can be moved out of `&mut` and `Box` with functions such as [`swap`], |
| 20 | +//! changing the location of the underlying data, [`Pin`] prohibits accessing the |
| 21 | +//! underlying pointer type (the `&mut` or `Box`) directly, and provides its own set of |
| 22 | +//! APIs for accessing and using the value. |
21 | 23 | //!
|
22 |
| -//! However, these restrictions are usually not necessary, |
23 |
| -//! so most types implement the [`Unpin`] auto-trait, |
24 |
| -//! which indicates that the type can be moved out safely. |
25 |
| -//! Doing so removes the limitations of pinning types, |
26 |
| -//! making them the same as their non-pinning counterparts. |
| 24 | +//! However, these restrictions are usually not necessary. Many types are always freely |
| 25 | +//! movable. These types implement the [`Unpin`] auto-trait, which nullifies the affect |
| 26 | +//! of [`Pin`]. For `T: Unpin`, `Pin<Box<T>>` and `Box<T>` function identically, as do |
| 27 | +//! `Pin<&mut T>` and `&mut T`. |
| 28 | +//! |
| 29 | +//! Note that pinning and `Unpin` only affect the pointed-to type. For example, whether |
| 30 | +//! or not `Box<T>` is `Unpin` has no affect on the behavior of `Pin<Box<T>>`. Similarly, |
| 31 | +//! `Pin<Box<T>>` and `Pin<&mut T>` are always `Unpin` themselves, even though the |
| 32 | +//! `T` underneath them isn't, because the pointers in `Pin<Box<_>>` and `Pin<&mut _>` |
| 33 | +//! are always freely movable, even if the data they point to isn't. |
27 | 34 | //!
|
28 | 35 | //! [`Pin`]: struct.Pin.html
|
29 | 36 | //! [`Unpin`]: trait.Unpin.html
|
|
0 commit comments