|
138 | 138 | //! To make this work, not just moving the data is restricted; deallocating, repurposing, or
|
139 | 139 | //! otherwise invalidating the memory used to store the data is restricted, too.
|
140 | 140 | //! Concretely, for pinned data you have to maintain the invariant
|
141 |
| -//! that *its memory will not get invalidated from the moment it gets pinned until |
| 141 | +//! that *its memory will not get invalidated or repurposed from the moment it gets pinned until |
142 | 142 | //! when `drop` is called*. Memory can be invalidated by deallocation, but also by
|
143 | 143 | //! replacing a [`Some(v)`] by [`None`], or calling [`Vec::set_len`] to "kill" some elements
|
144 |
| -//! off of a vector. |
| 144 | +//! off of a vector. It can be repurposed by using [`ptr::write`] to overwrite it without |
| 145 | +//! calling the destructor first. |
145 | 146 | //!
|
146 | 147 | //! This is exactly the kind of guarantee that the intrusive linked list from the previous
|
147 | 148 | //! section needs to function correctly.
|
|
194 | 195 | //! that turn `Pin<&mut Struct>` into a reference to the field, but what
|
195 | 196 | //! type should that reference have? Is it `Pin<&mut Field>` or `&mut Field`?
|
196 | 197 | //! The same question arises with the fields of an enum, and also when considering
|
197 |
| -//! container/wrapper types such as `Vec<T>`, `Box<T>`, or `RefCell<T>`. |
| 198 | +//! container/wrapper types such as [`Vec<T>`], [`Box<T>`], or [`RefCell<T>`]. |
198 | 199 | //! Also, this question arises for both mutable and shared references, we just
|
199 | 200 | //! use the more common case of mutable references here for illustration.
|
200 | 201 | //!
|
|
267 | 268 | //! 3. You must make sure that you uphold the [`Drop` guarantee][drop-guarantee]:
|
268 | 269 | //! once your struct is pinned, the memory that contains the
|
269 | 270 | //! content is not overwritten or deallocated without calling the content's destructors.
|
270 |
| -//! This can be tricky, as witnessed by `VecDeque<T>`: the destructor of `VecDeque<T>` can fail |
271 |
| -//! to call `drop` on all elements if one of the destructors panics. This violates the |
| 271 | +//! This can be tricky, as witnessed by [`VecDeque<T>`]: the destructor of `VecDeque<T>` |
| 272 | +//! can fail to call `drop` on all elements if one of the destructors panics. This violates the |
272 | 273 | //! `Drop` guarantee, because it can lead to elements being deallocated without
|
273 | 274 | //! their destructor being called. (`VecDeque` has no pinning projections, so this
|
274 | 275 | //! does not cause unsoundness.)
|
|
279 | 280 | //! that operation can be used to move a `T` out of a pinned `Struct<T>` -- which means
|
280 | 281 | //! pinning cannot be structural for the field holding this data.
|
281 | 282 | //!
|
282 |
| -//! For a more complex example of moving data out of a pinned type, imagine if `RefCell<T>` |
| 283 | +//! For a more complex example of moving data out of a pinned type, imagine if [`RefCell<T>`] |
283 | 284 | //! had a method `fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T>`.
|
284 | 285 | //! Then we could do the following:
|
285 | 286 | //! ```compile_fail
|
|
296 | 297 | //!
|
297 | 298 | //! ## Examples
|
298 | 299 | //!
|
299 |
| -//! For a type like `Vec<T>`, both possibilites (structural pinning or not) make sense. |
| 300 | +//! For a type like [`Vec<T>`], both possibilites (structural pinning or not) make sense. |
300 | 301 | //! A `Vec<T>` with structural pinning could have `get_pin`/`get_pin_mut` methods to get
|
301 | 302 | //! pinned references to elements. However, it could *not* allow calling
|
302 | 303 | //! `pop` on a pinned `Vec<T>` because that would move the (structurally pinned) contents!
|
|
315 | 316 | //! whether the content is pinned is entirely independent of whether the pointer is
|
316 | 317 | //! pinned, meaning pinning is *not* structural.
|
317 | 318 | //!
|
318 |
| -//! When implementing a `Future` combinator, you will usually need structural pinning |
| 319 | +//! When implementing a [`Future`] combinator, you will usually need structural pinning |
319 | 320 | //! for the nested futures, as you need to get pinned references to them to call `poll`.
|
320 | 321 | //! But if your combinator contains any other data that does not need to be pinned,
|
321 | 322 | //! you can make those fields not structural and hence freely access them with a
|
|
329 | 330 | //! [`mem::swap`]: ../../std/mem/fn.swap.html
|
330 | 331 | //! [`mem::forget`]: ../../std/mem/fn.forget.html
|
331 | 332 | //! [`Box<T>`]: ../../std/boxed/struct.Box.html
|
| 333 | +//! [`Vec<T>`]: ../../std/vec/struct.Vec.html |
332 | 334 | //! [`Vec::set_len`]: ../../std/vec/struct.Vec.html#method.set_len
|
| 335 | +//! [`VecDeque<T>`]: ../../std/collections/struct.VecDeque.html |
| 336 | +//! [`RefCell<T>`]: ../../std/cell/struct.RefCell.html |
333 | 337 | //! [`None`]: ../../std/option/enum.Option.html#variant.None
|
334 | 338 | //! [`Some(v)`]: ../../std/option/enum.Option.html#variant.Some
|
| 339 | +//! [`ptr::write`]: ../ptr/fn.write.html |
| 340 | +//! [`Future`]: ../../std/future/trait.Future.html |
335 | 341 | //! [drop-impl]: #drop-implementation
|
336 | 342 | //! [drop-guarantee]: #drop-guarantee
|
337 | 343 |
|
|
0 commit comments