19
19
//! obtain a `Box` or reference to pinned data, which implies that you cannot use
20
20
//! operations such as [`mem::swap`]:
21
21
//! ```
22
+ //! use std::pin::Pin;
22
23
//! fn swap_pins<T>(x: Pin<&mut T>, y: Pin<&mut T>) {
23
24
//! // `mem::swap` needs `&mut T`, but we cannot get it.
24
25
//! // We are stuck, we cannot swap the contents of these references.
32
33
//! prevents certain *values* (pointed to by pointers wrapped in `Pin`) from being
33
34
//! moved by making it impossible to call methods like [`mem::swap`] on them.
34
35
//!
36
+ //! [`Pin`] can be used to wrap any pointer type, and as such it interacts with
37
+ //! [`Deref`] and [`DerefMut`]. A `Pin<P>` where `P: Deref` should be considered
38
+ //! as a "`P`-style pointer" to a pinned `P::Target` -- so, a `Pin<Box<T>>` is
39
+ //! an owned pointer to a pinned `T`, and a `Pin<Rc<T>>` is a reference-counted
40
+ //! pointer to a pinned `T`.
41
+ //! For correctness, [`Pin`] relies on the [`Deref`] and [`DerefMut`] implementations
42
+ //! to not move out of their `self` parameter, and to only ever return a pointer
43
+ //! to pinned data when they are called on a pinned pointer.
44
+ //!
35
45
//! # `Unpin`
36
46
//!
37
47
//! However, these restrictions are usually not necessary. Many types are always freely
114
124
//! list element will patch the pointers of its predecessor and successor to remove itself
115
125
//! from the list.
116
126
//!
117
- //! To make this work, it is crucial taht we can actually rely on `drop` being called.
127
+ //! To make this work, it is crucial that we can actually rely on `drop` being called.
118
128
//! And, in fact, this is a guarantee that `Pin` provides.
119
129
//!
120
130
//! # `Drop` guarantee
219
229
//!
220
230
//! [`Pin`]: struct.Pin.html
221
231
//! [`Unpin`]: ../../std/marker/trait.Unpin.html
232
+ //! [`Deref`]: ../../std/ops/trait.Deref.html
233
+ //! [`DerefMut`]: ../../std/ops/trait.DerefMut.html
222
234
//! [`mem::swap`]: ../../std/mem/fn.swap.html
223
235
//! [`mem::forget`]: ../../std/mem/fn.forget.html
224
236
//! [`Box`]: ../../std/boxed/struct.Box.html
@@ -319,16 +331,16 @@ impl<P: Deref> Pin<P> {
319
331
/// Construct a new `Pin` around a reference to some data of a type that
320
332
/// may or may not implement `Unpin`.
321
333
///
334
+ /// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used
335
+ /// instead.
336
+ ///
322
337
/// # Safety
323
338
///
324
339
/// This constructor is unsafe because we cannot guarantee that the data
325
340
/// pointed to by `pointer` is pinned, meaning that the data will not be moved or
326
341
/// its storage invalidated until it gets dropped. If the constructed `Pin<P>` does
327
342
/// not guarantee that the data `P` points to is pinned, constructing a
328
- /// `Pin<P>` is unsafe. In particular, calling `Pin::new_unchecked`
329
- /// on an `&'a mut T` is unsafe because while you are able to pin it for the given
330
- /// lifetime `'a`, you have no control over whether it is kept pinned once `'a`
331
- /// ends. A value, once pinned, must remain pinned forever (unless its type implements `Unpin`).
343
+ /// `Pin<P>` is unsafe. In particular,
332
344
///
333
345
/// By using this method, you are making a promise about the `P::Deref` and
334
346
/// `P::DerefMut` implementations, if they exist. Most importantly, they
@@ -340,21 +352,38 @@ impl<P: Deref> Pin<P> {
340
352
/// must not be possible to obtain a `&mut P::Target` and then
341
353
/// move out of that reference (using, for example [`mem::swap`]).
342
354
///
343
- /// For example, the following is a *violation* of `Pin`'s safety:
355
+ /// For example, calling `Pin::new_unchecked`
356
+ /// on an `&'a mut T` is unsafe because while you are able to pin it for the given
357
+ /// lifetime `'a`, you have no control over whether it is kept pinned once `'a` ends:
344
358
/// ```
345
359
/// use std::mem;
346
360
/// use std::pin::Pin;
347
361
///
348
- /// fn foo <T>(mut a: T, mut b: T) {
362
+ /// fn move_pinned_ref <T>(mut a: T, mut b: T) {
349
363
/// unsafe { let p = Pin::new_unchecked(&mut a); } // should mean `a` can never move again
350
364
/// mem::swap(&mut a, &mut b);
351
365
/// // the address of `a` changed to `b`'s stack slot, so `a` got moved even
352
366
/// // though we have previously pinned it!
353
367
/// }
354
368
/// ```
369
+ /// A value, once pinned, must remain pinned forever (unless its type implements `Unpin`).
355
370
///
356
- /// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used
357
- /// instead.
371
+ /// Similarily, calling `Pin::new_unchecked` on a `Rc<T>` is unsafe because there could be
372
+ /// aliases to the same data that are not subject to the pinning restrictions:
373
+ /// ```
374
+ /// use std::rc::Rc;
375
+ /// use std::pin::Pin;
376
+ ///
377
+ /// fn move_pinned_rc<T>(mut x: Rc<T>) {
378
+ /// let pinned = unsafe { Pin::new_unchecked(x.clone()) };
379
+ /// { let p: Pin<&T> = pinned.as_ref(); } // should mean the pointee can never move again
380
+ /// drop(pinned);
381
+ /// let content = Rc::get_mut(&mut x).unwrap();
382
+ /// // Now, if `x` was the only reference, we have a mutable reference to
383
+ /// // data that we pinned above, which we could use to move it as we have
384
+ /// // seen in the previous example.
385
+ /// }
386
+ /// ```
358
387
///
359
388
/// [`mem::swap`]: ../../std/mem/fn.swap.html
360
389
#[ stable( feature = "pin" , since = "1.33.0" ) ]
0 commit comments