|
10 | 10 | //!
|
11 | 11 | //! is called "pinning." We would say that a value which satisfies these guarantees has been
|
12 | 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]. |
| 13 | +//! location in memory, as though pinned to a pinboard. Pinning a value is incredibly useful in |
| 14 | +//! that it provides the necessary guarantees[^guarantees] for [`unsafe`] code to be able to |
| 15 | +//! dereference raw pointers to the pinned value for the duration it is pinned (which, |
| 16 | +//! [as we'll see later][drop-guarantee], is necessarily from the time the value is first pinned |
| 17 | +//! until the end of its lifetime). This concept of "pinning" is necessary to implement safe |
| 18 | +//! interfaces on top of things like self-referential types and intrusive data structures which |
| 19 | +//! cannot currently be modeled in fully safe Rust using only borrow-checked |
| 20 | +//! [references][reference]. |
20 | 21 | //!
|
21 | 22 | //! "Pinning" allows us to put a *value* which exists at some location in memory into a state where
|
22 | 23 | //! safe code cannot *move* that value to a different location in memory or otherwise invalidate it
|
23 | 24 | //! 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. |
| 25 | +//! [talk about below][self#unpin]). Anything that wants to interact with the pinned value in a way |
| 26 | +//! that has the potential to violate these guarantees must promise that it will not actually |
| 27 | +//! violate them, using the [`unsafe`] keyword to mark that such a promise is upheld by the user |
| 28 | +//! and not the compiler. In this way, we can allow other [`unsafe`] code to rely on any pointers |
| 29 | +//! that point to the pinned value to be valid to dereference while it is pinned. |
29 | 30 | //!
|
30 | 31 | //! [^guarantees]: Pinning on its own does not provide *all* the invariants necessary here. However,
|
31 | 32 | //! in order to validly pin a value in the first place, it must already satisfy the other invariants
|
|
61 | 62 | //! [`Copy`]ing a value from one place in memory to another. In Rust, "move" carries with it the
|
62 | 63 | //! semantics of ownership transfer from one variable to another, which is the key difference
|
63 | 64 | //! between a [`Copy`] and a move. For the purposes of this module's documentation, however, when
|
64 |
| -//! we write *move* in italics, we mean *specifically* that the value has moved in the mechanical |
| 65 | +//! we write *move* in italics, we mean *specifically* that the value has *moved* in the mechanical |
65 | 66 | //! sense of being located at a new place in memory.
|
66 | 67 | //!
|
67 | 68 | //! All values in Rust are trivially *moveable*. This means that the address at which a value is
|
|
184 | 185 | //! will not be *moved* or [otherwise invalidated][subtle-details].
|
185 | 186 | //!
|
186 | 187 | //! We call such a [`Pin`]-wrapped pointer a **pinning pointer,** (or pinning reference, or pinning
|
187 |
| -//! `Box`, etc.) because its existince is the thing that is pinning the underlying pointee in place: |
188 |
| -//! it is the metaphorical "pin" securing the data in place on the pinboard (in memory). |
| 188 | +//! `Box`, etc.) because its existince is the thing that is *symbolically* pinning the underlying |
| 189 | +//! pointee in place: it is the metaphorical "pin" securing the data in place on the pinboard |
| 190 | +//! (in memory). |
| 191 | +//! |
| 192 | +//! Notice that the thing wrapped by [`Pin`] is not the value which we want to pin itself, but |
| 193 | +//! rather a pointer to that value! A [`Pin<Ptr>`] does not pin the `Ptr`; instead, it pins the |
| 194 | +//! pointer's ***pointee** value*. |
| 195 | +//! |
| 196 | +//! ### Pinning as a library contract |
| 197 | +//! |
| 198 | +//! Pinning does not require nor make use of any compiler "magic"[^noalias], only a specific |
| 199 | +//! contract between the [`unsafe`] parts of a library API and its users. |
| 200 | +//! |
| 201 | +//! It is important to stress this point as a user of the [`unsafe`] parts of the [`Pin`] API. |
| 202 | +//! Practically, this means that performing the mechanics of "pinning" a value by creating a |
| 203 | +//! [`Pin<Ptr>`] to it *does not* actually change the way the compiler behaves towards the |
| 204 | +//! inner value! It is possible to use incorrect [`unsafe`] code to create a [`Pin<Ptr>`] to a |
| 205 | +//! value which does not actually satisfy the invariants that a pinned value must satisfy, and in |
| 206 | +//! this way lead undefined behavior even in (from that point) fully safe code. Similarly, using |
| 207 | +//! [`unsafe`], one may get access to a bare [`&mut T`] from a [`Pin<Ptr>`] and |
| 208 | +//! juse that to invalidly *move* pinned the value out. It is the job of the user of the |
| 209 | +//! [`unsafe`] parts of the [`Pin`] API to ensure these invariants are not violated. |
| 210 | +//! |
| 211 | +//! This differs from e.g. [`UnsafeCell`] which changes the semantics of a program's compiled |
| 212 | +//! output. A [`Pin<Ptr>`] is a handle to a value which we have promised we will not move out of, |
| 213 | +//! but Rust still considers all values themselves to be fundamentally moveable through, *e.g.* |
| 214 | +//! assignment or [`mem::replace`]. |
189 | 215 | //!
|
190 |
| -//! It is important to stress that the thing in the [`Pin`] is not the value which we want to pin |
191 |
| -//! itself, but rather a pointer to that value! A [`Pin<Ptr>`] does not pin the `Ptr` but rather |
192 |
| -//! the pointer's ***pointee** value*. |
| 216 | +//! [^noalias]: There is a bit of nuance here that is still being decided about what the aliasing |
| 217 | +//! semantics of `Pin<&mut T>` should be, but this is true as of today. |
| 218 | +//! |
| 219 | +//! ### How [`Pin`] prevents misuse in safe code |
193 | 220 | //!
|
194 | 221 | //! In order to accomplish the goal of pinning the pointee value, [`Pin<Ptr>`] restricts access to
|
195 | 222 | //! the wrapped `Ptr` type in safe code. Specifically, [`Pin`] disallows the ability to access
|
|
199 | 226 | //! through that <code>[&mut] T</code> it would be possible to *move* the underlying value out of
|
200 | 227 | //! the pointer with [`mem::replace`], etc.
|
201 | 228 | //!
|
202 |
| -//! This promise must be upheld manually by [`unsafe`] code which interacts with the [`Pin<Ptr>`] |
203 |
| -//! so that other [`unsafe`] code can rely on the pointee value being *un-moved* and valid. |
204 |
| -//! Interfaces that operate on values which are in an address-sensitive state accept an argument |
205 |
| -//! like <code>[Pin]<[&mut] T></code> or <code>[Pin]<[Box]\<T>></code> to indicate this contract to |
206 |
| -//! the caller. |
| 229 | +//! As discussed above, this promise must be upheld manually by [`unsafe`] code which interacts |
| 230 | +//! with the [`Pin<Ptr>`] so that other [`unsafe`] code can rely on the pointee value being |
| 231 | +//! *un-moved* and valid. Interfaces that operate on values which are in an address-sensitive state |
| 232 | +//! accept an argument like <code>[Pin]<[&mut] T></code> or <code>[Pin]<[Box]\<T>></code> to |
| 233 | +//! indicate this contract to the caller. |
207 | 234 | //!
|
208 |
| -//! [As discussed below][drop-guarantee], this has consequences for running |
209 |
| -//! destructors of pinned memory, too. |
| 235 | +//! [As discussed below][drop-guarantee], opting in to using pinning guarantees in the interface |
| 236 | +//! of an address-sensitive type has consequences for the implementation of some safe traits on |
| 237 | +//! that type as well. |
210 | 238 | //!
|
211 | 239 | //! ## Interaction between [`Deref`] and [`Pin<Ptr>`]
|
212 | 240 | //!
|
213 | 241 | //! Since [`Pin<Ptr>`] can wrap any pointer type, it uses [`Deref`] and [`DerefMut`] in
|
214 | 242 | //! order to identify the type of the pinned pointee data and provide (restricted) access to it.
|
215 | 243 | //!
|
216 |
| -//! A [`Pin<Ptr>`] where [`Ptr: Deref`][Deref] is a "`Ptr`-style pointer" to a pinned |
217 |
| -//! [`P::Target`][Target] – so, a <code>[Pin]<[Box]\<T>></code> is an owned pointer to a pinned `T`, |
218 |
| -//! and a <code>[Pin]<[Rc]\<T>></code> is a reference-counted pointer to a pinned `T`. |
| 244 | +//! A [`Pin<Ptr>`] where [`Ptr: Deref`][Deref] is a "`Ptr`-style pinning pointer" to a pinned |
| 245 | +//! [`P::Target`][Target] – so, a <code>[Pin]<[Box]\<T>></code> is an owned, pinning pointer to a |
| 246 | +//! pinned `T`, and a <code>[Pin]<[Rc]\<T>></code> is a reference-counted, pinning pointer to a |
| 247 | +//! pinned `T`. |
219 | 248 | //!
|
220 | 249 | //! [`Pin<Ptr>`] also uses the [`<Ptr as Deref>::Target`][Target] type information to modify the
|
221 | 250 | //! interface it is allowed to provide for interacting with that data (for example, when a
|
|
228 | 257 | //! types with such "malicious" implementations of [`Deref`]; see [`Pin<Ptr>::new_unchecked`] for
|
229 | 258 | //! details.
|
230 | 259 | //!
|
231 |
| -//! ## Pinning as a library contract |
232 |
| -//! |
233 |
| -//! Pinning does not require any compiler "magic"[^noalias], only a specific contract between the |
234 |
| -//! library API and its users. This differs from e.g. [`UnsafeCell`] which changes the semantics of |
235 |
| -//! a program's compiled output. A [`Pin<Ptr>`] is a handle to a value which does not allow moving |
236 |
| -//! the value out, but Rust still considers all values themselves to be moveable with e.g. |
237 |
| -//! [`mem::replace`]. |
238 |
| -//! |
239 |
| -//! [^noalias]: There is a bit of nuance here that is still being decided about what the aliasing |
240 |
| -//! semantics of `Pin<&mut T>` should be, but this is true as of today. |
241 |
| -//! |
242 | 260 | //! ## Fixing `AddrTracker`
|
243 | 261 | //!
|
244 | 262 | //! The guarantee of a stable address is necessary to make our `AddrTracker` example work. When
|
|
850 | 868 | //! [`std::alloc`]: ../../std/alloc/index.html
|
851 | 869 | //! [`Box<T>`]: ../../std/boxed/struct.Box.html
|
852 | 870 | //! [Box]: ../../std/boxed/struct.Box.html "Box"
|
| 871 | +//! [`Box`]: ../../std/boxed/struct.Box.html "Box" |
853 | 872 | //! [`Rc<T>`]: ../../std/rc/struct.Rc.html
|
854 | 873 | //! [Rc]: ../../std/rc/struct.Rc.html "rc::Rc"
|
855 | 874 | //! [`Vec<T>`]: ../../std/vec/struct.Vec.html
|
|
861 | 880 | //! [`Vec::set_len`]: ../../std/vec/struct.Vec.html#method.set_len
|
862 | 881 | //! [`VecDeque<T>`]: ../../std/collections/struct.VecDeque.html
|
863 | 882 | //! [VecDeque]: ../../std/collections/struct.VecDeque.html "collections::VecDeque"
|
| 883 | +//! [`String`]: ../../std/string/struct.String.html "String" |
864 | 884 |
|
865 | 885 | #![stable(feature = "pin", since = "1.33.0")]
|
866 | 886 |
|
|
0 commit comments