|
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