|
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