|
14 | 14 | //! for more details.
|
15 | 15 | //!
|
16 | 16 | //! By default, all types in Rust are movable. Rust allows passing all types by-value,
|
17 |
| -//! and common smart-pointer types such as <code>[Box]\<T></code> and <code>[&mut] T</code> allow replacing and |
18 |
| -//! moving the values they contain: you can move out of a <code>[Box]\<T></code>, or you can use [`mem::swap`]. |
19 |
| -//! <code>[Pin]\<P></code> wraps a pointer type `P`, so <code>[Pin]<[Box]\<T>></code> functions much like a regular |
20 |
| -//! <code>[Box]\<T></code>: when a <code>[Pin]<[Box]\<T>></code> gets dropped, so do its contents, and the memory gets |
21 |
| -//! deallocated. Similarly, <code>[Pin]<[&mut] T></code> is a lot like <code>[&mut] T</code>. However, <code>[Pin]\<P></code> does |
22 |
| -//! not let clients actually obtain a <code>[Box]\<T></code> or <code>[&mut] T</code> to pinned data, which implies that you |
23 |
| -//! cannot use operations such as [`mem::swap`]: |
| 17 | +//! and common smart-pointer types such as <code>[Box]\<T></code> and <code>[&mut] T</code> allow |
| 18 | +//! replacing and moving the values they contain: you can move out of a <code>[Box]\<T></code>, |
| 19 | +//! or you can use [`mem::swap`]. <code>[Pin]\<P></code> wraps a pointer type `P`, so |
| 20 | +//! <code>[Pin]<[Box]\<T>></code> functions much like a regular <code>[Box]\<T></code>: |
| 21 | +//! when a <code>[Pin]<[Box]\<T>></code> gets dropped, so do its contents, and the memory gets |
| 22 | +//! deallocated. Similarly, <code>[Pin]<[&mut] T></code> is a lot like <code>[&mut] T</code>. |
| 23 | +//! However, <code>[Pin]\<P></code> does not let clients actually obtain a <code>[Box]\<T></code> |
| 24 | +//! or <code>[&mut] T</code> to pinned data, which implies that you cannot use operations such |
| 25 | +//! as [`mem::swap`]: |
24 | 26 | //!
|
25 | 27 | //! ```
|
26 | 28 | //! use std::pin::Pin;
|
|
32 | 34 | //! }
|
33 | 35 | //! ```
|
34 | 36 | //!
|
35 |
| -//! It is worth reiterating that <code>[Pin]\<P></code> does *not* change the fact that a Rust compiler |
36 |
| -//! considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, <code>[Pin]\<P></code> |
37 |
| -//! prevents certain *values* (pointed to by pointers wrapped in <code>[Pin]\<P></code>) from being |
38 |
| -//! moved by making it impossible to call methods that require <code>[&mut] T</code> on them |
39 |
| -//! (like [`mem::swap`]). |
| 37 | +//! It is worth reiterating that <code>[Pin]\<P></code> does *not* change the fact that a Rust |
| 38 | +//! compiler considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, |
| 39 | +//! <code>[Pin]\<P></code> prevents certain *values* (pointed to by pointers wrapped in |
| 40 | +//! <code>[Pin]\<P></code>) from being moved by making it impossible to call methods that require |
| 41 | +//! <code>[&mut] T</code> on them (like [`mem::swap`]). |
40 | 42 | //!
|
41 | 43 | //! <code>[Pin]\<P></code> can be used to wrap any pointer type `P`, and as such it interacts with
|
42 |
| -//! [`Deref`] and [`DerefMut`]. A <code>[Pin]\<P></code> where <code>P: [Deref]</code> should be considered |
43 |
| -//! as a "`P`-style pointer" to a pinned <code>P::[Target]</code> – so, a <code>[Pin]<[Box]\<T>></code> is |
44 |
| -//! an owned pointer to a pinned `T`, and a <code>[Pin]<[Rc]\<T>></code> is a reference-counted |
45 |
| -//! pointer to a pinned `T`. |
| 44 | +//! [`Deref`] and [`DerefMut`]. A <code>[Pin]\<P></code> where <code>P: [Deref]</code> should be |
| 45 | +//! considered as a "`P`-style pointer" to a pinned <code>P::[Target]</code> – so, a |
| 46 | +//! <code>[Pin]<[Box]\<T>></code> is an owned pointer to a pinned `T`, and a |
| 47 | +//! <code>[Pin]<[Rc]\<T>></code> is a reference-counted pointer to a pinned `T`. |
46 | 48 | //! For correctness, <code>[Pin]\<P></code> relies on the implementations of [`Deref`] and
|
47 | 49 | //! [`DerefMut`] not to move out of their `self` parameter, and only ever to
|
48 | 50 | //! return a pointer to pinned data when they are called on a pinned pointer.
|
|
54 | 56 | //! [`bool`], [`i32`], and references) as well as types consisting solely of these
|
55 | 57 | //! types. Types that do not care about pinning implement the [`Unpin`]
|
56 | 58 | //! auto-trait, which cancels the effect of <code>[Pin]\<P></code>. For <code>T: [Unpin]</code>,
|
57 |
| -//! <code>[Pin]<[Box]\<T>></code> and <code>[Box]\<T></code> function identically, as do <code>[Pin]<[&mut] T></code> and |
58 |
| -//! <code>[&mut] T</code>. |
| 59 | +//! <code>[Pin]<[Box]\<T>></code> and <code>[Box]\<T></code> function identically, as do |
| 60 | +//! <code>[Pin]<[&mut] T></code> and <code>[&mut] T</code>. |
59 | 61 | //!
|
60 |
| -//! Note that pinning and [`Unpin`] only affect the pointed-to type <code>P::[Target]</code>, not the pointer |
61 |
| -//! type `P` itself that got wrapped in <code>[Pin]\<P></code>. For example, whether or not <code>[Box]\<T></code> is |
62 |
| -//! [`Unpin`] has no effect on the behavior of <code>[Pin]<[Box]\<T>></code> (here, `T` is the |
63 |
| -//! pointed-to type). |
| 62 | +//! Note that pinning and [`Unpin`] only affect the pointed-to type <code>P::[Target]</code>, |
| 63 | +//! not the pointer type `P` itself that got wrapped in <code>[Pin]\<P></code>. For example, |
| 64 | +//! whether or not <code>[Box]\<T></code> is [`Unpin`] has no effect on the behavior of |
| 65 | +//! <code>[Pin]<[Box]\<T>></code> (here, `T` is the pointed-to type). |
64 | 66 | //!
|
65 | 67 | //! # Example: self-referential struct
|
66 | 68 | //!
|
|
149 | 151 | //! when [`drop`] is called*. Only once [`drop`] returns or panics, the memory may be reused.
|
150 | 152 | //!
|
151 | 153 | //! Memory can be "invalidated" by deallocation, but also by
|
152 |
| -//! replacing a <code>[Some]\(v)</code> by [`None`], or calling [`Vec::set_len`] to "kill" some elements |
153 |
| -//! off of a vector. It can be repurposed by using [`ptr::write`] to overwrite it without |
| 154 | +//! replacing a <code>[Some]\(v)</code> by [`None`], or calling [`Vec::set_len`] to "kill" some |
| 155 | +//! elements off of a vector. It can be repurposed by using [`ptr::write`] to overwrite it without |
154 | 156 | //! calling the destructor first. None of this is allowed for pinned data without calling [`drop`].
|
155 | 157 | //!
|
156 | 158 | //! This is exactly the kind of guarantee that the intrusive linked list from the previous
|
|
172 | 174 | //! This can never cause a problem in safe code because implementing a type that
|
173 | 175 | //! relies on pinning requires unsafe code, but be aware that deciding to make
|
174 | 176 | //! use of pinning in your type (for example by implementing some operation on
|
175 |
| -//! <code>[Pin]<[&]Self></code> or <code>[Pin]<[&mut] Self></code>) has consequences for your [`Drop`][Drop] |
176 |
| -//! implementation as well: if an element of your type could have been pinned, |
| 177 | +//! <code>[Pin]<[&]Self></code> or <code>[Pin]<[&mut] Self></code>) has consequences for your |
| 178 | +//! [`Drop`][Drop]implementation as well: if an element of your type could have been pinned, |
177 | 179 | //! you must treat [`Drop`][Drop] as implicitly taking <code>[Pin]<[&mut] Self></code>.
|
178 | 180 | //!
|
179 | 181 | //! For example, you could implement [`Drop`][Drop] as follows:
|
|
206 | 208 | //! When working with pinned structs, the question arises how one can access the
|
207 | 209 | //! fields of that struct in a method that takes just <code>[Pin]<[&mut] Struct></code>.
|
208 | 210 | //! The usual approach is to write helper methods (so called *projections*)
|
209 |
| -//! that turn <code>[Pin]<[&mut] Struct></code> into a reference to the field, but what |
210 |
| -//! type should that reference have? Is it <code>[Pin]<[&mut] Field></code> or <code>[&mut] Field</code>? |
| 211 | +//! that turn <code>[Pin]<[&mut] Struct></code> into a reference to the field, but what type should |
| 212 | +//! that reference have? Is it <code>[Pin]<[&mut] Field></code> or <code>[&mut] Field</code>? |
211 | 213 | //! The same question arises with the fields of an `enum`, and also when considering
|
212 |
| -//! container/wrapper types such as <code>[Vec]\<T></code>, <code>[Box]\<T></code>, or <code>[RefCell]\<T></code>. |
213 |
| -//! (This question applies to both mutable and shared references, we just |
214 |
| -//! use the more common case of mutable references here for illustration.) |
| 214 | +//! container/wrapper types such as <code>[Vec]\<T></code>, <code>[Box]\<T></code>, |
| 215 | +//! or <code>[RefCell]\<T></code>. (This question applies to both mutable and shared references, |
| 216 | +//! we just use the more common case of mutable references here for illustration.) |
215 | 217 | //!
|
216 |
| -//! It turns out that it is actually up to the author of the data structure |
217 |
| -//! to decide whether the pinned projection for a particular field turns |
218 |
| -//! <code>[Pin]<[&mut] Struct></code> into <code>[Pin]<[&mut] Field></code> or <code>[&mut] Field</code>. There are some |
| 218 | +//! It turns out that it is actually up to the author of the data structure to decide whether |
| 219 | +//! the pinned projection for a particular field turns <code>[Pin]<[&mut] Struct></code> |
| 220 | +//! into <code>[Pin]<[&mut] Field></code> or <code>[&mut] Field</code>. There are some |
219 | 221 | //! constraints though, and the most important constraint is *consistency*:
|
220 | 222 | //! every field can be *either* projected to a pinned reference, *or* have
|
221 | 223 | //! pinning removed as part of the projection. If both are done for the same field,
|
|
283 | 285 | //! the principle that you only have to worry about any of this if you use [`unsafe`].)
|
284 | 286 | //! 2. The destructor of the struct must not move structural fields out of its argument. This
|
285 | 287 | //! is the exact point that was raised in the [previous section][drop-impl]: [`drop`] takes
|
286 |
| -//! <code>[&mut] self</code>, but the struct (and hence its fields) might have been pinned before. |
287 |
| -//! You have to guarantee that you do not move a field inside your [`Drop`][Drop] implementation. |
288 |
| -//! In particular, as explained previously, this means that your struct must *not* |
289 |
| -//! be `#[repr(packed)]`. |
| 288 | +//! <code>[&mut] self</code>, but the struct (and hence its fields) might have been pinned |
| 289 | +//! before. You have to guarantee that you do not move a field inside your [`Drop`][Drop] |
| 290 | +//! implementation. In particular, as explained previously, this means that your struct |
| 291 | +//! must *not* be `#[repr(packed)]`. |
290 | 292 | //! See that section for how to write [`drop`] in a way that the compiler can help you
|
291 | 293 | //! not accidentally break pinning.
|
292 | 294 | //! 3. You must make sure that you uphold the [`Drop` guarantee][drop-guarantee]:
|
293 | 295 | //! once your struct is pinned, the memory that contains the
|
294 | 296 | //! content is not overwritten or deallocated without calling the content's destructors.
|
295 |
| -//! This can be tricky, as witnessed by <code>[VecDeque]\<T></code>: the destructor of <code>[VecDeque]\<T></code> |
296 |
| -//! can fail to call [`drop`] on all elements if one of the destructors panics. This violates |
297 |
| -//! the [`Drop`][Drop] guarantee, because it can lead to elements being deallocated without |
298 |
| -//! their destructor being called. (<code>[VecDeque]\<T></code> has no pinning projections, so this |
| 297 | +//! This can be tricky, as witnessed by <code>[VecDeque]\<T></code>: the destructor of |
| 298 | +//! <code>[VecDeque]\<T></code> can fail to call [`drop`] on all elements if one of the |
| 299 | +//! destructors panics. This violates the [`Drop`][Drop] guarantee, because it can lead to |
| 300 | +//! elements being deallocated without their destructor being called. |
| 301 | +//! (<code>[VecDeque]\<T></code> has no pinning projections, so this |
299 | 302 | //! does not cause unsoundness.)
|
300 | 303 | //! 4. You must not offer any other operations that could lead to data being moved out of
|
301 | 304 | //! the structural fields when your type is pinned. For example, if the struct contains an
|
|
304 | 307 | //! that operation can be used to move a `T` out of a pinned `Struct<T>` – which means
|
305 | 308 | //! pinning cannot be structural for the field holding this data.
|
306 | 309 | //!
|
307 |
| -//! For a more complex example of moving data out of a pinned type, imagine if <code>[RefCell]\<T></code> |
308 |
| -//! had a method <code>fn get_pin_mut(self: [Pin]<[&mut] Self>) -> [Pin]<[&mut] T></code>. |
| 310 | +//! For a more complex example of moving data out of a pinned type, |
| 311 | +//! imagine if <code>[RefCell]\<T></code> had a method |
| 312 | +//! <code>fn get_pin_mut(self: [Pin]<[&mut] Self>) -> [Pin]<[&mut] T></code>. |
309 | 313 | //! Then we could do the following:
|
310 | 314 | //! ```compile_fail
|
311 | 315 | //! fn exploit_ref_cell<T>(rc: Pin<&mut RefCell<T>>) {
|
|
315 | 319 | //! let content = &mut *b; // And here we have `&mut T` to the same data.
|
316 | 320 | //! }
|
317 | 321 | //! ```
|
318 |
| -//! This is catastrophic, it means we can first pin the content of the <code>[RefCell]\<T></code> |
319 |
| -//! (using <code>[RefCell]::get_pin_mut</code>) and then move that content using the mutable |
320 |
| -//! reference we got later. |
| 322 | +//! This is catastrophic, it means we can first pin the content of the |
| 323 | +//! <code>[RefCell]\<T></code> (using <code>[RefCell]::get_pin_mut</code>) and then move that |
| 324 | +//! content using the mutable reference we got later. |
321 | 325 | //!
|
322 | 326 | //! ## Examples
|
323 | 327 | //!
|
324 |
| -//! For a type like <code>[Vec]\<T></code>, both possibilities (structural pinning or not) make sense. |
325 |
| -//! A <code>[Vec]\<T></code> with structural pinning could have `get_pin`/`get_pin_mut` methods to get |
326 |
| -//! pinned references to elements. However, it could *not* allow calling |
327 |
| -//! [`pop`][Vec::pop] on a pinned <code>[Vec]\<T></code> because that would move the (structurally pinned) |
328 |
| -//! contents! Nor could it allow [`push`][Vec::push], which might reallocate and thus also move the |
329 |
| -//! contents. |
| 328 | +//! For a type like <code>[Vec]\<T></code>, both possibilities (structural pinning or not) make |
| 329 | +//! sense. A <code>[Vec]\<T></code> with structural pinning could have `get_pin`/`get_pin_mut` |
| 330 | +//! methods to get pinned references to elements. However, it could *not* allow calling |
| 331 | +//! [`pop`][Vec::pop] on a pinned <code>[Vec]\<T></code> because that would move the (structurally |
| 332 | +//! pinned) contents! Nor could it allow [`push`][Vec::push], which might reallocate and thus also |
| 333 | +//! move the contents. |
330 | 334 | //!
|
331 |
| -//! A <code>[Vec]\<T></code> without structural pinning could <code>impl\<T> [Unpin] for [Vec]\<T></code>, because the contents |
332 |
| -//! are never pinned and the <code>[Vec]\<T></code> itself is fine with being moved as well. |
| 335 | +//! A <code>[Vec]\<T></code> without structural pinning could |
| 336 | +//! <code>impl\<T> [Unpin] for [Vec]\<T></code>, because the contents are never pinned |
| 337 | +//! and the <code>[Vec]\<T></code> itself is fine with being moved as well. |
333 | 338 | //! At that point pinning just has no effect on the vector at all.
|
334 | 339 | //!
|
335 | 340 | //! In the standard library, pointer types generally do not have structural pinning,
|
336 |
| -//! and thus they do not offer pinning projections. This is why <code>[Box]\<T>: [Unpin]</code> holds for all `T`. |
337 |
| -//! It makes sense to do this for pointer types, because moving the <code>[Box]\<T></code> |
338 |
| -//! does not actually move the `T`: the <code>[Box]\<T></code> can be freely movable (aka [`Unpin`]) even if |
339 |
| -//! the `T` is not. In fact, even <code>[Pin]<[Box]\<T>></code> and <code>[Pin]<[&mut] T></code> are always |
340 |
| -//! [`Unpin`] themselves, for the same reason: their contents (the `T`) are pinned, but the |
341 |
| -//! pointers themselves can be moved without moving the pinned data. For both <code>[Box]\<T></code> and |
342 |
| -//! <code>[Pin]<[Box]\<T>></code>, whether the content is pinned is entirely independent of whether the |
| 341 | +//! and thus they do not offer pinning projections. This is why <code>[Box]\<T>: [Unpin]</code> |
| 342 | +//! holds for all `T`. It makes sense to do this for pointer types, because moving the |
| 343 | +//! <code>[Box]\<T></code> does not actually move the `T`: the <code>[Box]\<T></code> can be freely |
| 344 | +//! movable (aka [`Unpin`]) even if the `T` is not. In fact, even <code>[Pin]<[Box]\<T>></code> and |
| 345 | +//! <code>[Pin]<[&mut] T></code> are always [`Unpin`] themselves, for the same reason: |
| 346 | +//! their contents (the `T`) are pinned, but the pointers themselves can be moved without moving |
| 347 | +//! the pinned data. For both <code>[Box]\<T></code> and <code>[Pin]<[Box]\<T>></code>, |
| 348 | +//! whether the content is pinned is entirely independent of whether the |
343 | 349 | //! pointer is pinned, meaning pinning is *not* structural.
|
344 | 350 | //!
|
345 | 351 | //! When implementing a [`Future`] combinator, you will usually need structural pinning
|
|
0 commit comments