Skip to content

Commit c489636

Browse files
committed
mention that overwrite-without-drop also violates the drop guarantee, and link some more stuff
1 parent b66dcb9 commit c489636

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

src/libcore/pin.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,11 @@
138138
//! To make this work, not just moving the data is restricted; deallocating, repurposing, or
139139
//! otherwise invalidating the memory used to store the data is restricted, too.
140140
//! 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
142142
//! when `drop` is called*. Memory can be invalidated by deallocation, but also by
143143
//! 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.
145146
//!
146147
//! This is exactly the kind of guarantee that the intrusive linked list from the previous
147148
//! section needs to function correctly.
@@ -194,7 +195,7 @@
194195
//! that turn `Pin<&mut Struct>` into a reference to the field, but what
195196
//! type should that reference have? Is it `Pin<&mut Field>` or `&mut Field`?
196197
//! 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>`].
198199
//! Also, this question arises for both mutable and shared references, we just
199200
//! use the more common case of mutable references here for illustration.
200201
//!
@@ -267,8 +268,8 @@
267268
//! 3. You must make sure that you uphold the [`Drop` guarantee][drop-guarantee]:
268269
//! once your struct is pinned, the memory that contains the
269270
//! 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
272273
//! `Drop` guarantee, because it can lead to elements being deallocated without
273274
//! their destructor being called. (`VecDeque` has no pinning projections, so this
274275
//! does not cause unsoundness.)
@@ -279,7 +280,7 @@
279280
//! that operation can be used to move a `T` out of a pinned `Struct<T>` -- which means
280281
//! pinning cannot be structural for the field holding this data.
281282
//!
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>`]
283284
//! had a method `fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T>`.
284285
//! Then we could do the following:
285286
//! ```compile_fail
@@ -296,7 +297,7 @@
296297
//!
297298
//! ## Examples
298299
//!
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.
300301
//! A `Vec<T>` with structural pinning could have `get_pin`/`get_pin_mut` methods to get
301302
//! pinned references to elements. However, it could *not* allow calling
302303
//! `pop` on a pinned `Vec<T>` because that would move the (structurally pinned) contents!
@@ -315,7 +316,7 @@
315316
//! whether the content is pinned is entirely independent of whether the pointer is
316317
//! pinned, meaning pinning is *not* structural.
317318
//!
318-
//! When implementing a `Future` combinator, you will usually need structural pinning
319+
//! When implementing a [`Future`] combinator, you will usually need structural pinning
319320
//! for the nested futures, as you need to get pinned references to them to call `poll`.
320321
//! But if your combinator contains any other data that does not need to be pinned,
321322
//! you can make those fields not structural and hence freely access them with a
@@ -329,9 +330,14 @@
329330
//! [`mem::swap`]: ../../std/mem/fn.swap.html
330331
//! [`mem::forget`]: ../../std/mem/fn.forget.html
331332
//! [`Box<T>`]: ../../std/boxed/struct.Box.html
333+
//! [`Vec<T>`]: ../../std/vec/struct.Vec.html
332334
//! [`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
333337
//! [`None`]: ../../std/option/enum.Option.html#variant.None
334338
//! [`Some(v)`]: ../../std/option/enum.Option.html#variant.Some
339+
//! [`ptr::write`]: ../ptr/fn.write.html
340+
//! [`Future`]: ../../std/future/trait.Future.html
335341
//! [drop-impl]: #drop-implementation
336342
//! [drop-guarantee]: #drop-guarantee
337343

0 commit comments

Comments
 (0)