| 
163 | 163 | //! first option is ruled out.  | 
164 | 164 | //!  | 
165 | 165 | //! In order to implement the second option, we must in some way enforce its key invariant,  | 
166 |  | -//! *i.e.* prevent the value from being *moved* or otherwise invalidated. (You may notice this  | 
167 |  | -//! sounds an awful lot like the definition of *pinning* a value). There are two ways by  | 
168 |  | -//! which we might enforce this validity invariant in Rust:  | 
 | 166 | +//! *i.e.* prevent the value from being *moved* or otherwise invalidated (you may notice this  | 
 | 167 | +//! sounds an awful lot like the definition of *pinning* a value). There a few ways one might be  | 
 | 168 | +//! able to enforce this invariant in Rust:  | 
169 | 169 | //!  | 
170 | 170 | //! 1. Offer a wholly `unsafe` API to interact with the object, thus requiring every caller to  | 
171 |  | -//! uphold the invariant themselves; or,  | 
172 |  | -//! 2. Leverage the type system to encode and enforce this invariant by presenting a restricted  | 
173 |  | -//! API surface to interact with the object  | 
 | 171 | +//! uphold the invariant themselves  | 
 | 172 | +//! 2. Store the value that must not be moved behind a carefully managed pointer internal to  | 
 | 173 | +//! the object  | 
 | 174 | +//! 3. Leverage the type system to encode and enforce this invariant by presenting a restricted  | 
 | 175 | +//! API surface to interact with *any* object that requires these invariants  | 
174 | 176 | //!  | 
175 |  | -//! The first option is quite obviously undesirable, as the `unsafe`ty of the interface will  | 
 | 177 | +//! The first option is quite obviously undesirable, as the [`unsafe`]ty of the interface will  | 
176 | 178 | //! become viral throughout all code that interacts with the object.  | 
177 | 179 | //!  | 
178 |  | -//! [`Pin<Ptr>`] is an implementation of the second option, allowing us to pin a value in place  | 
179 |  | -//! until its [`drop`] runs in a way that we can depend on it staying valid in `unsafe` code.  | 
 | 180 | +//! The second option is a viable solution to the problem for some use cases, in particular  | 
 | 181 | +//! for self-referrential types. Under this model, any type that has an address sensitive state  | 
 | 182 | +//! would ultimately store its data in something like a [`Box<T>`] and then carefully manage  | 
 | 183 | +//! the access to that data internally to ensure no *moves* or other invalidation occur, then  | 
 | 184 | +//! provide a safe interface on top.  | 
 | 185 | +//!  | 
 | 186 | +//! There are a couple of linked disadvantages to using this model. The core issue is a lack  | 
 | 187 | +//! of generality. This is an issue first because it means hat each individual type that  | 
 | 188 | +//! implements such an interface does so on its own. Each individual developer must themselves  | 
 | 189 | +//! think through all the guarantees needed to ensure the API they present is sound. This puts  | 
 | 190 | +//! a greater burden on each developer, rather than allowing building a shared understanding of the  | 
 | 191 | +//! problem space, encoded into a shared interface to solve it. In addition, and the key issue that  | 
 | 192 | +//! drove Rust towards another solution, is that each individual object must assume it is on its  | 
 | 193 | +//! own in ensuring that its data does not become *moved* or otherwise invalidated. Since there is  | 
 | 194 | +//! no shared contract between values of different types, an object cannot assume that others  | 
 | 195 | +//! interacting with it will be a good citizen with its data. Because of this, *composition* of  | 
 | 196 | +//! address-sensitive types requires at least a level of pointer indirection (and, practically, a  | 
 | 197 | +//! heap allocation) each time a new object is added to the mix. This is particularly a problem  | 
 | 198 | +//! when one considers the implications of composing together the [`Future`]s which will eventaully  | 
 | 199 | +//! make up an asynchronous task (including address-sensitive `async fn` state machines).  | 
 | 200 | +//! It is plausible that there could be many layers of [`Future`]s composed together, including  | 
 | 201 | +//! multiple layers of `async fn`s handling different parts of a task, and it was deemed  | 
 | 202 | +//! unacceptable to force indirection and allocation for each layer of composition in this case.  | 
 | 203 | +//!  | 
 | 204 | +//! [`Pin<Ptr>`] is an implementation of the third option. It allows us to solve the issues  | 
 | 205 | +//! discussed with the second option by building a *shared contractual language* around the  | 
 | 206 | +//! guarantees of "pinning" data.  | 
180 | 207 | //!  | 
181 | 208 | //! ## Using [`Pin<Ptr>`] to pin values  | 
182 | 209 | //!  | 
 | 
0 commit comments