6
6
//! since moving an object with pointers to itself will invalidate them,
7
7
//! which could cause undefined behavior.
8
8
//!
9
- //! [`Pin`] ensures that the pointee of any pointer type has a stable location in memory,
9
+ //! A [`Pin<P> `] ensures that the pointee of any pointer type `P` has a stable location in memory,
10
10
//! meaning it cannot be moved elsewhere and its memory cannot be deallocated
11
11
//! until it gets dropped. We say that the pointee is "pinned".
12
12
//!
13
13
//! By default, all types in Rust are movable. Rust allows passing all types by-value,
14
- //! and common smart-pointer types such as `Box` and `&mut` allow replacing and
15
- //! moving the values they contain: you can move out of a `Box`, or you can use [`mem::swap`].
16
- //! [`Pin`] wraps a pointer type, so `Pin<Box<T>>` functions much like a regular `Box<T>`
17
- //! ( when a `Pin<Box<T>>` gets dropped, so do its contents, and the memory gets deallocated) .
18
- //! Similarily, `Pin<&mut T>` is a lot like `&mut T`. However, [`Pin`] does not let clients actually
14
+ //! and common smart-pointer types such as `Box<T> ` and `&mut T ` allow replacing and
15
+ //! moving the values they contain: you can move out of a `Box<T> `, or you can use [`mem::swap`].
16
+ //! [`Pin<P> `] wraps a pointer type `P` , so `Pin<Box<T>>` functions much like a regular `Box<T>`:
17
+ //! when a `Pin<Box<T>>` gets dropped, so do its contents, and the memory gets deallocated.
18
+ //! Similarily, `Pin<&mut T>` is a lot like `&mut T`. However, [`Pin<P> `] does not let clients actually
19
19
//! obtain a `Box<T>` or `&mut T` to pinned data, which implies that you cannot use
20
20
//! operations such as [`mem::swap`]:
21
21
//! ```
28
28
//! }
29
29
//! ```
30
30
//!
31
- //! It is worth reiterating that [`Pin`] does *not* change the fact that a Rust compiler
32
- //! considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, `Pin`
33
- //! prevents certain *values* (pointed to by pointers wrapped in `Pin`) from being
31
+ //! It is worth reiterating that [`Pin<P> `] does *not* change the fact that a Rust compiler
32
+ //! considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, `Pin<P> `
33
+ //! prevents certain *values* (pointed to by pointers wrapped in `Pin<P> `) from being
34
34
//! moved by making it impossible to call methods that require `&mut T` on them
35
35
//! (like [`mem::swap`]).
36
36
//!
37
- //! [`Pin`] can be used to wrap any pointer type, and as such it interacts with
37
+ //! [`Pin<P> `] can be used to wrap any pointer type `P` , and as such it interacts with
38
38
//! [`Deref`] and [`DerefMut`]. A `Pin<P>` where `P: Deref` should be considered
39
39
//! as a "`P`-style pointer" to a pinned `P::Target` -- so, a `Pin<Box<T>>` is
40
40
//! an owned pointer to a pinned `T`, and a `Pin<Rc<T>>` is a reference-counted
41
41
//! pointer to a pinned `T`.
42
- //! For correctness, [`Pin`] relies on the [`Deref`] and [`DerefMut`] implementations
42
+ //! For correctness, [`Pin<P> `] relies on the [`Deref`] and [`DerefMut`] implementations
43
43
//! to not move out of their `self` parameter, and to only ever return a pointer
44
44
//! to pinned data when they are called on a pinned pointer.
45
45
//!
50
50
//! This includes all the basic types (`bool`, `i32` and friends, references)
51
51
//! as well as types consisting solely of these types.
52
52
//! Types that do not care about pinning implement the [`Unpin`] auto-trait, which
53
- //! nullifies the effect of [`Pin`]. For `T: Unpin`, `Pin<Box<T>>` and `Box<T>` function
53
+ //! cancels the effect of [`Pin<P> `]. For `T: Unpin`, `Pin<Box<T>>` and `Box<T>` function
54
54
//! identically, as do `Pin<&mut T>` and `&mut T`.
55
55
//!
56
56
//! Note that pinning and `Unpin` only affect the pointed-to type, not the pointer
57
- //! type itself that got wrapped in `Pin`. For example, whether or not `Box<T>` is
57
+ //! type `P` itself that got wrapped in `Pin<P> `. For example, whether or not `Box<T>` is
58
58
//! `Unpin` has no effect on the behavior of `Pin<Box<T>>` (here, `T` is the
59
59
//! pointed-to type).
60
60
//!
120
120
//! and elements can live on a stack frame that lives shorter than the collection does.
121
121
//!
122
122
//! To make this work, every element has pointers to its predecessor and successor in
123
- //! the list. Element can only be added when they are pinned, because moving the elements
123
+ //! the list. Elements can only be added when they are pinned, because moving the elements
124
124
//! around would invalidate the pointers. Moreover, the `Drop` implementation of a linked
125
125
//! list element will patch the pointers of its predecessor and successor to remove itself
126
126
//! from the list.
129
129
//! could be deallocated or otherwise invalidated without calling `drop`, the pointers into it
130
130
//! from its neighbouring elements would become invalid, which would break the data structure.
131
131
//!
132
- //! This is why pinning also comes with a `drop`-related guarantee.
132
+ //! Therefore, pinning also comes with a `drop`-related guarantee.
133
133
//!
134
134
//! # `Drop` guarantee
135
135
//!
136
136
//! The purpose of pinning is to be able to rely on the placement of some data in memory.
137
- //! To make this work, not just moving the data is restricted; deallocating, repurposing or
137
+ //! To make this work, not just moving the data is restricted; deallocating, repurposing, or
138
138
//! otherwise invalidating the memory used to store the data is restricted, too.
139
139
//! Concretely, for pinned data you have to maintain the invariant
140
140
//! that *its memory will not get invalidated from the moment it gets pinned until
141
141
//! when `drop` is called*. Memory can be invalidated by deallocation, but also by
142
- //! replacing a `Some(v)` by `None`, or calling `Vec::set_len` to "kill" some elements
142
+ //! replacing a [ `Some(v)`] by [ `None`] , or calling [ `Vec::set_len`] to "kill" some elements
143
143
//! off of a vector.
144
144
//!
145
145
//! This is exactly the kind of guarantee that the intrusive linked list from the previous
174
174
//! One interesting question arises when considering the interaction of pinning and
175
175
//! the fields of a struct. When can a struct have a "pinning projection", i.e.,
176
176
//! an operation with type `fn(Pin<&[mut] Struct>) -> Pin<&[mut] Field>`?
177
- //! In a similar vein, when can a generic wrapper type (such as `Vec`, `Box`, or `RefCell`)
177
+ //! In a similar vein, when can a generic wrapper type (such as `Vec<T> `, `Box<T> `, or `RefCell<T> `)
178
178
//! have an operation with type `fn(Pin<&[mut] Wrapper<T>>) -> Pin<&[mut] T>`?
179
179
//!
180
180
//! Having a pinning projection for some field means that pinning is "structural":
199
199
//! 3. You must make sure that you uphold the [`Drop` guarantee][drop-guarantee]:
200
200
//! once your wrapper is pinned, the memory that contains the
201
201
//! content is not overwritten or deallocated without calling the content's destructors.
202
- //! This can be tricky, as witnessed by `VecDeque`: the destructor of `VecDeque` can fail
202
+ //! This can be tricky, as witnessed by `VecDeque<T> `: the destructor of `VecDeque<T> ` can fail
203
203
//! to call `drop` on all elements if one of the destructors panics. This violates the
204
204
//! `Drop` guarantee, because it can lead to elements being deallocated without
205
205
//! their destructor being called. (`VecDeque` has no pinning projections, so this
208
208
//! the fields when your type is pinned. For example, if the wrapper contains an
209
209
//! `Option<T>` and there is a `take`-like operation with type
210
210
//! `fn(Pin<&mut Wrapper<T>>) -> Option<T>`,
211
- //! that operation can be used to move a `T` out of a pinned `Wrapper` -- which means
211
+ //! that operation can be used to move a `T` out of a pinned `Wrapper<T> ` -- which means
212
212
//! pinning cannot be structural.
213
213
//!
214
- //! For a more complex example of moving data out of a pinnd type, imagine if `RefCell`
214
+ //! For a more complex example of moving data out of a pinned type, imagine if `RefCell<T> `
215
215
//! had a method `fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T>`.
216
216
//! Then we could do the following:
217
217
//! ```compile_fail
218
218
//! fn exploit_ref_cell<T>(rc: Pin<&mut RefCell<T>) {
219
- //! { let p = rc.as_mut().get_pin_mut(); } // here we get pinned access to the `T`
219
+ //! { let p = rc.as_mut().get_pin_mut(); } // Here we get pinned access to the `T`.
220
220
//! let rc_shr: &RefCell<T> = rc.into_ref().get_ref();
221
221
//! let b = rc_shr.borrow_mut();
222
- //! let content = &mut *b; // and here we have `&mut T` to the same data
222
+ //! let content = &mut *b; // And here we have `&mut T` to the same data.
223
223
//! }
224
224
//! ```
225
- //! This is catastrophic, it means we can first pin the content of the `RefCell`
225
+ //! This is catastrophic, it means we can first pin the content of the `RefCell<T> `
226
226
//! (using `RefCell::get_pin_mut`) and then move that content using the mutable
227
227
//! reference we got later.
228
228
//!
229
- //! For a type like `Vec`, both possibilites (structural pinning or not) make sense,
230
- //! and the choice is up to the author. A `Vec` with structural pinning could
229
+ //! For a type like `Vec<T> `, both possibilites (structural pinning or not) make sense,
230
+ //! and the choice is up to the author. A `Vec<T> ` with structural pinning could
231
231
//! have `get_pin`/`get_pin_mut` projections. However, it could *not* allow calling
232
- //! `pop` on a pinned `Vec` because that would move the (structurally pinned) contents!
232
+ //! `pop` on a pinned `Vec<T> ` because that would move the (structurally pinned) contents!
233
233
//! Nor could it allow `push`, which might reallocate and thus also move the contents.
234
- //! A `Vec` without structural pinning could `impl<T> Unpin for Vec<T>`, because the contents
235
- //! are never pinned and the `Vec` itself is fine with being moved as well.
234
+ //! A `Vec<T> ` without structural pinning could `impl<T> Unpin for Vec<T>`, because the contents
235
+ //! are never pinned and the `Vec<T> ` itself is fine with being moved as well.
236
236
//!
237
237
//! In the standard library, pointer types generally do not have structural pinning,
238
238
//! and thus they do not offer pinning projections. This is why `Box<T>: Unpin` holds for all `T`.
244
244
//! whether the content is pinned is entirely independent of whether the pointer is
245
245
//! pinned, meaning pinning is *not* structural.
246
246
//!
247
- //! [`Pin`]: struct.Pin.html
247
+ //! [`Pin<P> `]: struct.Pin.html
248
248
//! [`Unpin`]: ../../std/marker/trait.Unpin.html
249
249
//! [`Deref`]: ../../std/ops/trait.Deref.html
250
250
//! [`DerefMut`]: ../../std/ops/trait.DerefMut.html
251
251
//! [`mem::swap`]: ../../std/mem/fn.swap.html
252
252
//! [`mem::forget`]: ../../std/mem/fn.forget.html
253
- //! [`Box`]: ../../std/boxed/struct.Box.html
253
+ //! [`Box<T>`]: ../../std/boxed/struct.Box.html
254
+ //! [`Vec::set_len`]: ../../std/vec/struct.Vec.html#method.set_len
255
+ //! [`None`]: ../../std/option/enum.Option.html#variant.None
256
+ //! [`Some(v)`]: ../../std/option/enum.Option.html#variant.Some
254
257
//! [drop-impl]: #drop-implementation
255
258
//! [drop-guarantee]: #drop-guarantee
256
259
@@ -328,11 +331,11 @@ impl<P: Deref> Pin<P>
328
331
where
329
332
P :: Target : Unpin ,
330
333
{
331
- /// Construct a new `Pin` around a pointer to some data of a type that
334
+ /// Construct a new `Pin<P> ` around a pointer to some data of a type that
332
335
/// implements [`Unpin`].
333
336
///
334
337
/// Unlike `Pin::new_unchecked`, this method is safe because the pointer
335
- /// `P` dereferences to an [`Unpin`] type, which nullifies the pinning guarantees.
338
+ /// `P` dereferences to an [`Unpin`] type, which cancels the pinning guarantees.
336
339
///
337
340
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
338
341
#[ stable( feature = "pin" , since = "1.33.0" ) ]
@@ -345,7 +348,7 @@ where
345
348
}
346
349
347
350
impl < P : Deref > Pin < P > {
348
- /// Construct a new `Pin` around a reference to some data of a type that
351
+ /// Construct a new `Pin<P> ` around a reference to some data of a type that
349
352
/// may or may not implement `Unpin`.
350
353
///
351
354
/// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used
@@ -379,13 +382,13 @@ impl<P: Deref> Pin<P> {
379
382
/// fn move_pinned_ref<T>(mut a: T, mut b: T) {
380
383
/// unsafe { let p = Pin::new_unchecked(&mut a); } // should mean `a` can never move again
381
384
/// mem::swap(&mut a, &mut b);
382
- /// // the address of `a` changed to `b`'s stack slot, so `a` got moved even
385
+ /// // The address of `a` changed to `b`'s stack slot, so `a` got moved even
383
386
/// // though we have previously pinned it!
384
387
/// }
385
388
/// ```
386
389
/// A value, once pinned, must remain pinned forever (unless its type implements `Unpin`).
387
390
///
388
- /// Similarily, calling `Pin::new_unchecked` on a `Rc<T>` is unsafe because there could be
391
+ /// Similarily, calling `Pin::new_unchecked` on an `Rc<T>` is unsafe because there could be
389
392
/// aliases to the same data that are not subject to the pinning restrictions:
390
393
/// ```
391
394
/// use std::rc::Rc;
@@ -482,7 +485,7 @@ impl<'a, T: ?Sized> Pin<&'a T> {
482
485
/// It may seem like there is an issue here with interior mutability: in fact,
483
486
/// it *is* possible to move a `T` out of a `&RefCell<T>`. However, this is
484
487
/// not a problem as long as there does not also exist a `Pin<&T>` pointing
485
- /// to the same data, and `RefCell` does not let you create a pinned reference
488
+ /// to the same data, and `RefCell<T> ` does not let you create a pinned reference
486
489
/// to its contents. See the discussion on ["pinning projections"] for further
487
490
/// details.
488
491
///
0 commit comments