|
1 | 1 | //! Types that pin data to a location in memory.
|
2 | 2 | //!
|
3 | 3 | //! It is sometimes useful to be able to rely upon a certain value not being able to *move*,
|
4 |
| -//! in the sense that its address in memory cannot change. This is useful specifically when there |
5 |
| -//! are one or more *pointers* pointing at that value. The ability to rely on this guarantee that |
6 |
| -//! the value a pointer is pointing at (its **pointee**) will |
| 4 | +//! in the sense that its address in memory cannot change. This is useful especially when there |
| 5 | +//! are one or more [*pointers*][pointer] pointing at that value. The ability to rely on this |
| 6 | +//! guarantee that the value a [pointer] is pointing at (its **pointee**) will |
7 | 7 | //!
|
8 | 8 | //! 1. Not be *moved* out of its memory location
|
9 | 9 | //! 2. More generally, remain *valid* at that same memory location
|
10 | 10 | //!
|
11 |
| -//! is necessary to implement things like self-referential structs and intrusive data structures. |
12 |
| -//! |
13 |
| -//! "Pinning" allows us to put a value *which is being pointed at* by some pointer `Ptr` into a |
14 |
| -//! state that prevents safe code from *moving* or otherwise invalidating the *pointee* value at |
15 |
| -//! its location in memory (unless the pointee type implements [`Unpin`], which we'll |
16 |
| -//! [discuss more below][self#unpin]). In this way, we can allow [`unsafe`] code to rely on the |
17 |
| -//! pointer to be valid to dereference. |
| 11 | +//! is called "pinning." We would say that a value which satisfies these guarantees has been |
| 12 | +//! "pinned," in that it has been permanently (until the end of its lifetime) attached to its |
| 13 | +//! location in memory. Pinning a value is incredibly useful in that it provides the necessary |
| 14 | +//! guarantees[^guarantees] for [`unsafe`] code to be able to dereference raw pointers to the pinned |
| 15 | +//! value for the duration it is pinned (which, [as we'll see later][drop-guarantee], is necessarily |
| 16 | +//! from the time the value is first pinned until the end of its lifetime). This concept of |
| 17 | +//! "pinning" is necessary to implement safe interfaces on top of things like self-referential types |
| 18 | +//! and intrusive data structures which cannot currently be modeled in fully safe Rust using only |
| 19 | +//! borrow-checked [references][reference]. |
| 20 | +//! |
| 21 | +//! "Pinning" allows us to put a *value* which exists at some location in memory into a state where |
| 22 | +//! safe code cannot *move* that value to a different location in memory or otherwise invalidate it |
| 23 | +//! at its current location (unless it implements [`Unpin`], which we will |
| 24 | +//! [talk about below][unpin]). Anything that wants to interact with the pinned value in a way that |
| 25 | +//! has the potential to violate these guarantees must promise that it will not actually violate |
| 26 | +//! them, using the [`unsafe`] keyword to mark that such a promise is upheld by the user and not |
| 27 | +//! the compiler. In this way, we can allow other [`unsafe`] code to rely on any pointers that |
| 28 | +//! point to the pinned value to be valid to dereference while it is pinned. |
| 29 | +//! |
| 30 | +//! [^guarantees]: Pinning on its own does not provide *all* the invariants necessary here. However, |
| 31 | +//! in order to validly pin a value in the first place, it must already satisfy the other invariants |
| 32 | +//! for it to be valid to dereference a pointer to that value while it is pinned, and using the |
| 33 | +//! [`Drop` guarantee][drop-guarantee], we can ensure that any interested parties are notified |
| 34 | +//! before the value becomes no longer pinned, i.e. when the value goes out of scope and is |
| 35 | +//! invalidated. |
| 36 | +//! |
| 37 | +//! Note that as long as you don't use [`unsafe`], it's impossible to create or misuse a pinned |
| 38 | +//! value in a way that will produce unsoundness. See the documentation of [`Pin<Ptr>`] for more |
| 39 | +//! information on the practicalities of how to pin a value and how to use that pinned value from a |
| 40 | +//! user's perspective without using [`unsafe`]. |
18 | 41 | //!
|
19 | 42 | //! The rest of this documentation is intended to be the source of truth for users of [`Pin<Ptr>`]
|
20 |
| -//! in unsafe code; users of [`Pin<Ptr>`] in safe code do not need to read it in detail. |
| 43 | +//! that are implementing the [`unsafe`] pieces of an interface that relies on pinning for validity; |
| 44 | +//! users of [`Pin<Ptr>`] in safe code do not need to read it in detail. |
21 | 45 | //!
|
22 | 46 | //! There are several sections to this documentation:
|
23 | 47 | //!
|
24 | 48 | //! * [What is "*moving*"?][what-is-moving]
|
25 | 49 | //! * [What is "pinning"?][what-is-pinning]
|
| 50 | +//! * [Address sensitivity, AKA "when do we need pinning?"][address-sensitive-values] |
26 | 51 | //! * [Examples of types with address-sensitive states][address-sensitive-examples]
|
27 | 52 | //! * [Self-referential struct][self-ref]
|
28 | 53 | //! * [Intrusive, doubly-linked list][linked-list]
|
|
90 | 115 | //! to remain *valid* and *located at the same place in memory* from the time it is pinned until its
|
91 | 116 | //! [`drop`] is called.
|
92 | 117 | //!
|
93 |
| -//! ## Address-sensitive values, AKA "why we need pinning" |
94 |
| -//! [address-sensitive-values]: self#address-sensitive-values |
| 118 | +//! ## Address-sensitive values, AKA "when we need pinning" |
| 119 | +//! [address-sensitive-values]: self#address-sensitive-values-aka-when-we-need-pinning |
95 | 120 | //!
|
96 | 121 | //! Most values in Rust are entirely okay with being *moved* around at-will.
|
97 | 122 | //! Types for which it is *always* the case that *any* value of that type can be
|
|
105 | 130 | //!
|
106 | 131 | //! As a motivating example of a type which may become address-sensitive, consider a type which
|
107 | 132 | //! contains a pointer to another piece of its own data, *i.e.* a "self-referential" type. In order
|
108 |
| -//! such a type to be implemented soundly, the pointer which points into `self`'s data must be |
| 133 | +//! for such a type to be implemented soundly, the pointer which points into `self`'s data must be |
109 | 134 | //! proven valid whenever it is accessed. But if that value is *moved*, the pointer will still
|
110 |
| -//! point to the old location that the value was located and not into the new location of `self`, |
| 135 | +//! point to the old address where the value was located and not into the new location of `self`, |
111 | 136 | //! thus becoming invalid. A key example of such self-referrential types are the state machines
|
112 | 137 | //! generated by the compiler to implement [`Future`] for `async fn`s.
|
113 | 138 | //!
|
|
122 | 147 | //! assume that the address of the value is stable
|
123 | 148 | //! * e.g. subsequent calls to [`poll`]
|
124 | 149 | //! 4. Before the value is invalidated (e.g. deallocated), it is *dropped*, giving it a chance to
|
125 |
| -//! "unregister"/clear outstanding pointers to itself |
| 150 | +//! notify anything with pointers to itself that those pointers will be invalidated |
126 | 151 | //! * e.g. [`drop`]ping the [`Future`]
|
127 | 152 | //!
|
128 | 153 | //! There are two possible ways to ensure the invariants required for 2. and 3. above (which
|
|
229 | 254 | //! #[derive(Default)]
|
230 | 255 | //! struct AddrTracker {
|
231 | 256 | //! prev_addr: Option<usize>,
|
232 |
| -//! // remove auto-implemented Unpin bound to mark this type as having some |
233 |
| -//! // address-sensitive state. This is discussed more below. |
| 257 | +//! // remove auto-implemented `Unpin` bound to mark this type as having some |
| 258 | +//! // address-sensitive state. This is essential for our expected pinning |
| 259 | +//! // guarantees to work, and is discussed more below. |
234 | 260 | //! _pin: PhantomPinned,
|
235 | 261 | //! }
|
236 | 262 | //!
|
|
273 | 299 | //!
|
274 | 300 | //! The vast majority of Rust types have no address-sensitive states; these types
|
275 | 301 | //! implement the [`Unpin`] auto-trait, which cancels the restrictive effects of
|
276 |
| -//! [`Pin<P>`]. When [`T: Unpin`][Unpin], <code>[Pin]<[Box]\<T>></code> and |
277 |
| -//! [`Box<T>`] function identically, as do <code>[Pin]<[&mut] T></code> and |
278 |
| -//! [`&mut T`]. |
| 302 | +//! [`Pin`] when the *pointee* type `T` is [`Unpin`]. When [`T: Unpin`][Unpin], |
| 303 | +//! <code>[Pin]<[Box]\<T>></code> functions identically to a non-pinning [`Box<T>`]; similarly, |
| 304 | +//! <code>[Pin]<[&mut] T></code> would impose no additional restrictions above a regular [`&mut T`]. |
| 305 | +//! |
| 306 | +//! Note that the interaction between a [`Pin<Ptr>`] and [`Unpin`] is through the type of the |
| 307 | +//! **pointee** value, [`<Ptr as Deref>::Target`][Target]. Whether the `Ptr` type itself |
| 308 | +//! implements [`Unpin`] does not affect the behavior of a [`Pin<Ptr>`]. For example, whether or not |
| 309 | +//! [`Box`] is [`Unpin`] has no effect on the behavior of <code>[Pin]<[Box]\<T>></code>, because |
| 310 | +//! `T` is the type of the pointee value, not [`Box`]. So, whether `T` implements [`Unpin`] is |
| 311 | +//! the thing that will affect the behavior of the <code>[Pin]<[Box]\<T>></code>. |
279 | 312 | //!
|
280 |
| -//! This includes all of the primitive types, like [`bool`], [`i32`], and <code>[&]T</code>, |
281 |
| -//! as well as any other type consisting only of those types. |
| 313 | +//! Builtin types that are [`Unpin`] include all of the primitive types, like [`bool`], [`i32`], |
| 314 | +//! and [`f32`], references (<code>[&]T</code> and <code>[&mut] T</code>), etc., as well as many |
| 315 | +//! core and standard library types like [`Box<T>`], [`String`], and more. |
| 316 | +//! These types are marked [`Unpin`] because they do not have an ddress-sensitive state like the |
| 317 | +//! ones we discussed above. If they did have such a state, those parts of their interface would be |
| 318 | +//! unsound without being expressed through pinning, and they would then need to not |
| 319 | +//! implement [`Unpin`]. |
| 320 | +//! |
| 321 | +//! The compiler (and users!) is free to take the conservative stance of marking types as [`Unpin`] |
| 322 | +//! by default. This is because if a type implements [`Unpin`], then it is unsound for [`unsafe`] |
| 323 | +//! code to assume that type is truly pinned, *even* when viewed through a "pinning" pointer! It is |
| 324 | +//! the responsibility of *the implementor of [`unsafe`] code that relies upon pinning for |
| 325 | +//! soundness* (you, in this case!) to ensure that all the types which that code expects to be truly |
| 326 | +//! pinned do not implement [`Unpin`]. |
282 | 327 | //!
|
283 | 328 | //! Like other auto-traits, the compiler will automatically determine that a type implements
|
284 |
| -//! [`Unpin`] if all its fields also implement [`Unpin`]. If you are building a type which is built |
| 329 | +//! [`Unpin`] if all its fields also implement [`Unpin`]. If you are building a type which consists |
285 | 330 | //! of only [`Unpin`] types but has an address-sensistive state and thus should not itself
|
286 |
| -//! implement [`Unpin`], you can opt out of [`Unpin`] via adding a field with the |
287 |
| -//! [`PhantomPinned`] marker type, as we did with our latest `AddrTracker` example above. |
288 |
| -//! |
289 |
| -//! Note that the interaction between a [`Pin<Ptr>`] and [`Unpin`] is through the **pointee type** |
290 |
| -//! of the value behind the `Ptr`, [`<Ptr as Deref>::Target`][Target]. Whether the `Ptr` type itself |
291 |
| -//! implements [`Unpin`] does not affect the behavior of a [`Pin<Ptr>`]. For example, whether or not |
292 |
| -//! [`Box<T>`] is [`Unpin`] has no effect on the behavior of <code>[Pin]<[Box]\<T>></code> because |
293 |
| -//! `T` is the type of the pointee value, not [`Box<T>`]. So, whether `T` implements [`Unpin`] is |
294 |
| -//! the thing that will affect the behavior of the <code>[Pin]<[Box]\<T>></code>. |
| 331 | +//! implement [`Unpin`], you must opt out of [`Unpin`] via adding a field with the |
| 332 | +//! [`PhantomPinned`] marker type, as we did with our latest `AddrTracker` example above. Without |
| 333 | +//! doing this, you must not rely on the pinning guarantees to apply to your type! |
| 334 | +//! |
| 335 | +//! If you have reason to pin a value of a type that implements [`Unpin`] such that pinning-related |
| 336 | +//! guarantees actually are respected, you'll need to create your own wrapper type which itself |
| 337 | +//! opts out of implementing [`Unpin`] and contains a sub-field with the [`Unpin`] type that you |
| 338 | +//! want to pin. |
| 339 | +//! |
| 340 | +//! Exposing access to the inner field which you want to remain pinned must then be carefully |
| 341 | +//! considered as well! Remember, exposing a method that gives access to a |
| 342 | +//! <code>[Pin]<[&mut] InnerT>></code> where `InnerT: [Unpin]` would allow safe code to trivially |
| 343 | +//! move the inner value out of that pinning pointer, which is precisely what you're seeking to |
| 344 | +//! prevent! Exposing a field of a pinned value through a pinning pointer is called "projecting" |
| 345 | +//! a pin, and the more general case of deciding in which cases a pin should be able to be |
| 346 | +//! projected or not is called "structural pinning." We will go into more detail about this |
| 347 | +//! [below][structural-pinning]. |
295 | 348 | //!
|
296 | 349 | //! # Examples of address-sensitive types
|
297 | 350 | //! [address-sensitive-examples]: #examples-of-address-sensitive-types
|
|
308 | 361 | //! we could imagine being used to track a sliding window of `data` in parser
|
309 | 362 | //! code.
|
310 | 363 | //!
|
311 |
| -//! As mentioned before, this pattern is used extensively by compiler-generated |
| 364 | +//! As mentioned before, this pattern is also used extensively by compiler-generated |
312 | 365 | //! [`Future`]s.
|
313 | 366 | //!
|
314 | 367 | //! ```rust
|
|
379 | 432 | //! ## An intrusive, doubly-linked list
|
380 | 433 | //! [linked-list]: #an-intrusive-doubly-linked-list
|
381 | 434 | //!
|
382 |
| -//! In an intrusive doubly-linked list, the collection does not actually allocate the memory for the |
383 |
| -//! nodes itself. Allocation is controlled by the clients, and nodes can live on a stack frame |
384 |
| -//! that lives shorter than the collection does provided the nodes are removed from the |
385 |
| -//! collection before returning. |
| 435 | +//! In an intrusive doubly-linked list, the collection itself does not own the memory in which |
| 436 | +//! each of its elements is stored. Instead, each client is free to allocate space for elements it |
| 437 | +//! adds to the list in whichever manner it likes, including on the stack! Elements can live on a |
| 438 | +//! stack frame that lives shorter than the collection does provided the elements that live in a |
| 439 | +//! given stack frame are removed from the list before going out of scope. |
| 440 | +//! |
| 441 | +//! To make such an intrusive data structure work, every element stores pointers to its predecessor |
| 442 | +//! and successor within its own data, rather than having the list structure itself managing those |
| 443 | +//! pointers. It is in this sense that the structure is "intrusive": the details of how an |
| 444 | +//! element is stored within the larger structure "intrudes" on the implementation of the element |
| 445 | +//! type itself! |
386 | 446 | //!
|
387 | 447 | //! The full implementation details of such a data structure are outside the scope of this
|
388 | 448 | //! documentation, but we will discuss how [`Pin`] can help to do so.
|
389 | 449 | //!
|
390 |
| -//! To make such an intrusive data structure work, every element stores pointers to its predecessor |
391 |
| -//! and successor within its own data, rather than having the list structure itself manage those |
392 |
| -//! pointers. Elements can only be added when they are pinned, because moving the elements |
393 |
| -//! around would invalidate the pointers to it which are contained in the element ahead and behind |
394 |
| -//! it. Moreover, the [`Drop`][Drop] implementation of the element types themselves will in some |
395 |
| -//! way patch the pointers of its predecessor and successor elements to remove itself from the list. |
| 450 | +//! Using such an intrusive pattern, elements may only be added when they are pinned. If we think |
| 451 | +//! about the consequences of adding non-pinned values to such a list, this becomes clear: |
| 452 | +//! |
| 453 | +//! *Moving* or otherwise invalidating an element's data would invalidate the pointers back to it |
| 454 | +//! which are stored in the elements ahead and behind it. Thus, in order to soundly dereference |
| 455 | +//! the pointers stored to the next and previous elements, we must satisfy the guarantee that |
| 456 | +//! nothing has invalidated those pointers (which point to data which we do not own). |
| 457 | +//! |
| 458 | +//! Moreover, the [`Drop`][Drop] implementation of each element must in some way notify its |
| 459 | +//! predecessor and successor elements that it should be removed from the list before it is fully |
| 460 | +//! destroyed, otherwise the pointers back to it would again become invalidated. |
396 | 461 | //!
|
397 |
| -//! Crucially, this means we have to be able to rely on [`drop`] always being called before that |
| 462 | +//! Crucially, this means we have to be able to rely on [`drop`] always being called before an |
398 | 463 | //! element is invalidated. If an element could be deallocated or otherwise invalidated without
|
399 |
| -//! calling [`drop`], the pointers into it which are stored in its neighboring elements would |
| 464 | +//! calling [`drop`], the pointers to it which are stored in its neighboring elements would |
400 | 465 | //! become invalid, which would break the data structure.
|
401 | 466 | //!
|
402 |
| -//! Therefore, we rely on [the `Drop` guarantee][drop-guarantee] which comes with pinning data, |
| 467 | +//! Therefore, pinning data also comes with [the "`Drop` guarantee"][drop-guarantee]. |
403 | 468 | //!
|
404 | 469 | //! # Subtle details and the `Drop` guarantee
|
405 | 470 | //! [subtle-details]: self#subtle-details-and-the-drop-guarantee
|
|
586 | 651 | //! the new value.
|
587 | 652 | //!
|
588 | 653 | //! ## Projections and Structural Pinning
|
| 654 | +//! [structural-pinning]: self#projections-and-structural-pinning |
589 | 655 | //!
|
590 | 656 | //! With ordinary structs, it is natural that we want to add *projection* methods
|
591 | 657 | //! that select one of the fields:
|
|
0 commit comments