Skip to content

Commit 0076f58

Browse files
committedDec 12, 2018
Auto merge of #55992 - cramertj:pin-docs, r=alexcrichton
Expand std::pin module docs and rename std::pin::Pinned to PhantomPinned cc #49150, #55766 r? @withoutboats
2 parents dd8fc7d + 709b751 commit 0076f58

File tree

2 files changed

+32
-22
lines changed

2 files changed

+32
-22
lines changed
 

‎src/libcore/marker.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -640,15 +640,15 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
640640
#[unstable(feature = "pin", issue = "49150")]
641641
pub auto trait Unpin {}
642642

643-
/// A type which does not implement `Unpin`.
643+
/// A marker type which does not implement `Unpin`.
644644
///
645-
/// If a type contains a `Pinned`, it will not implement `Unpin` by default.
645+
/// If a type contains a `PhantomPinned`, it will not implement `Unpin` by default.
646646
#[unstable(feature = "pin", issue = "49150")]
647647
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
648-
pub struct Pinned;
648+
pub struct PhantomPinned;
649649

650650
#[unstable(feature = "pin", issue = "49150")]
651-
impl !Unpin for Pinned {}
651+
impl !Unpin for PhantomPinned {}
652652

653653
#[unstable(feature = "pin", issue = "49150")]
654654
impl<'a, T: ?Sized + 'a> Unpin for &'a T {}

‎src/libcore/pin.rs

+28-18
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,33 @@
77
//! since moving an object with pointers to itself will invalidate them,
88
//! which could cause undefined behavior.
99
//!
10-
//! In order to prevent objects from moving, they must be pinned
11-
//! by wrapping a pointer to the data in the [`Pin`] type. A pointer wrapped
12-
//! in a `Pin` is otherwise equivalent to its normal version, e.g., `Pin<Box<T>>`
13-
//! and `Box<T>` work the same way except that the first is pinning the value
14-
//! of `T` in place.
10+
//! By default, all types in Rust are movable. Rust allows passing all types by-value,
11+
//! and common smart-pointer types such as `Box`, `Rc`, and `&mut` allow replacing and
12+
//! moving the values they contain. In order to prevent objects from moving, they must
13+
//! be pinned by wrapping a pointer to the data in the [`Pin`] type.
14+
//! Doing this prohibits moving the value behind the pointer.
15+
//! For example, `Pin<Box<T>>` functions much like a regular `Box<T>`,
16+
//! but doesn't allow moving `T`. The pointer value itself (the `Box`) can still be moved,
17+
//! but the value behind it cannot.
1518
//!
16-
//! First of all, these are pointer types because pinned data mustn't be passed around by value
17-
//! (that would change its location in memory).
18-
//! Secondly, since data can be moved out of `&mut` and `Box` with functions such as [`swap`],
19-
//! which causes their contents to swap places in memory,
20-
//! we need dedicated types that prohibit such operations.
19+
//! Since data can be moved out of `&mut` and `Box` with functions such as [`swap`],
20+
//! changing the location of the underlying data, [`Pin`] prohibits accessing the
21+
//! underlying pointer type (the `&mut` or `Box`) directly, and provides its own set of
22+
//! APIs for accessing and using the value. [`Pin`] also guarantees that no other
23+
//! functions will move the pointed-to value. This allows for the creation of
24+
//! self-references and other special behaviors that are only possible for unmovable
25+
//! values.
2126
//!
22-
//! However, these restrictions are usually not necessary,
23-
//! so most types implement the [`Unpin`] auto-trait,
24-
//! which indicates that the type can be moved out safely.
25-
//! Doing so removes the limitations of pinning types,
26-
//! making them the same as their non-pinning counterparts.
27+
//! However, these restrictions are usually not necessary. Many types are always freely
28+
//! movable. These types implement the [`Unpin`] auto-trait, which nullifies the affect
29+
//! of [`Pin`]. For `T: Unpin`, `Pin<Box<T>>` and `Box<T>` function identically, as do
30+
//! `Pin<&mut T>` and `&mut T`.
31+
//!
32+
//! Note that pinning and `Unpin` only affect the pointed-to type. For example, whether
33+
//! or not `Box<T>` is `Unpin` has no affect on the behavior of `Pin<Box<T>>`. Similarly,
34+
//! `Pin<Box<T>>` and `Pin<&mut T>` are always `Unpin` themselves, even though the
35+
//! `T` underneath them isn't, because the pointers in `Pin<Box<_>>` and `Pin<&mut _>`
36+
//! are always freely movable, even if the data they point to isn't.
2737
//!
2838
//! [`Pin`]: struct.Pin.html
2939
//! [`Unpin`]: trait.Unpin.html
@@ -36,7 +46,7 @@
3646
//! #![feature(pin)]
3747
//!
3848
//! use std::pin::Pin;
39-
//! use std::marker::Pinned;
49+
//! use std::marker::PhantomPinned;
4050
//! use std::ptr::NonNull;
4151
//!
4252
//! // This is a self-referential struct since the slice field points to the data field.
@@ -47,7 +57,7 @@
4757
//! struct Unmovable {
4858
//! data: String,
4959
//! slice: NonNull<String>,
50-
//! _pin: Pinned,
60+
//! _pin: PhantomPinned,
5161
//! }
5262
//!
5363
//! impl Unmovable {
@@ -60,7 +70,7 @@
6070
//! // we only create the pointer once the data is in place
6171
//! // otherwise it will have already moved before we even started
6272
//! slice: NonNull::dangling(),
63-
//! _pin: Pinned,
73+
//! _pin: PhantomPinned,
6474
//! };
6575
//! let mut boxed = Box::pinned(res);
6676
//!

0 commit comments

Comments
 (0)
Please sign in to comment.