Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing type links in documentation #62120

Merged
merged 1 commit into from
Jul 26, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 81 additions & 63 deletions src/libcore/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
//! until it gets dropped. We say that the pointee is "pinned".
//!
//! By default, all types in Rust are movable. Rust allows passing all types by-value,
//! and common smart-pointer types such as `Box<T>` and `&mut T` allow replacing and
//! moving the values they contain: you can move out of a `Box<T>`, or you can use [`mem::swap`].
//! [`Pin<P>`] wraps a pointer type `P`, so `Pin<Box<T>>` functions much like a regular `Box<T>`:
//! when a `Pin<Box<T>>` gets dropped, so do its contents, and the memory gets deallocated.
//! Similarly, `Pin<&mut T>` is a lot like `&mut T`. However, [`Pin<P>`] does not let clients
//! actually obtain a `Box<T>` or `&mut T` to pinned data, which implies that you cannot use
//! operations such as [`mem::swap`]:
//! and common smart-pointer types such as [`Box<T>`] and `&mut T` allow replacing and
//! moving the values they contain: you can move out of a [`Box<T>`], or you can use [`mem::swap`].
//! [`Pin<P>`] wraps a pointer type `P`, so [`Pin`]`<`[`Box`]`<T>>` functions much like a regular
//! [`Box<T>`]: when a [`Pin`]`<`[`Box`]`<T>>` gets dropped, so do its contents, and the memory gets
//! deallocated. Similarly, [`Pin`]`<&mut T>` is a lot like `&mut T`. However, [`Pin<P>`] does
//! not let clients actually obtain a [`Box<T>`] or `&mut T` to pinned data, which implies that you
//! cannot use operations such as [`mem::swap`]:
//!
//! ```
//! use std::pin::Pin;
Expand All @@ -30,15 +30,15 @@
//! ```
//!
//! It is worth reiterating that [`Pin<P>`] does *not* change the fact that a Rust compiler
//! considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, `Pin<P>`
//! prevents certain *values* (pointed to by pointers wrapped in `Pin<P>`) from being
//! considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, [`Pin<P>`]
//! prevents certain *values* (pointed to by pointers wrapped in [`Pin<P>`]) from being
//! moved by making it impossible to call methods that require `&mut T` on them
//! (like [`mem::swap`]).
//!
//! [`Pin<P>`] can be used to wrap any pointer type `P`, and as such it interacts with
//! [`Deref`] and [`DerefMut`]. A `Pin<P>` where `P: Deref` should be considered
//! as a "`P`-style pointer" to a pinned `P::Target` -- so, a `Pin<Box<T>>` is
//! an owned pointer to a pinned `T`, and a `Pin<Rc<T>>` is a reference-counted
//! [`Deref`] and [`DerefMut`]. A [`Pin<P>`] where `P: Deref` should be considered
//! as a "`P`-style pointer" to a pinned `P::Target` -- so, a [`Pin`]`<`[`Box`]`<T>>` is
//! an owned pointer to a pinned `T`, and a [`Pin`]`<`[`Rc`]`<T>>` is a reference-counted
//! pointer to a pinned `T`.
//! For correctness, [`Pin<P>`] relies on the implementations of [`Deref`] and
//! [`DerefMut`] not to move out of their `self` parameter, and only ever to
Expand All @@ -48,15 +48,15 @@
//!
//! Many types are always freely movable, even when pinned, because they do not
//! rely on having a stable address. This includes all the basic types (like
//! `bool`, `i32`, and references) as well as types consisting solely of these
//! [`bool`], [`i32`], and references) as well as types consisting solely of these
//! types. Types that do not care about pinning implement the [`Unpin`]
//! auto-trait, which cancels the effect of [`Pin<P>`]. For `T: Unpin`,
//! `Pin<Box<T>>` and `Box<T>` function identically, as do `Pin<&mut T>` and
//! [`Pin`]`<`[`Box`]`<T>>` and [`Box<T>`] function identically, as do [`Pin`]`<&mut T>` and
//! `&mut T`.
//!
//! Note that pinning and `Unpin` only affect the pointed-to type `P::Target`, not the pointer
//! type `P` itself that got wrapped in `Pin<P>`. For example, whether or not `Box<T>` is
//! `Unpin` has no effect on the behavior of `Pin<Box<T>>` (here, `T` is the
//! Note that pinning and [`Unpin`] only affect the pointed-to type `P::Target`, not the pointer
//! type `P` itself that got wrapped in [`Pin<P>`]. For example, whether or not [`Box<T>`] is
//! [`Unpin`] has no effect on the behavior of [`Pin`]`<`[`Box`]`<T>>` (here, `T` is the
//! pointed-to type).
//!
//! # Example: self-referential struct
Expand Down Expand Up @@ -122,15 +122,15 @@
//!
//! To make this work, every element has pointers to its predecessor and successor in
//! the list. Elements can only be added when they are pinned, because moving the elements
//! around would invalidate the pointers. Moreover, the `Drop` implementation of a linked
//! around would invalidate the pointers. Moreover, the [`Drop`] implementation of a linked
//! list element will patch the pointers of its predecessor and successor to remove itself
//! from the list.
//!
//! Crucially, we have to be able to rely on `drop` being called. If an element
//! could be deallocated or otherwise invalidated without calling `drop`, the pointers into it
//! Crucially, we have to be able to rely on [`drop`] being called. If an element
//! could be deallocated or otherwise invalidated without calling [`drop`], the pointers into it
//! from its neighbouring elements would become invalid, which would break the data structure.
//!
//! Therefore, pinning also comes with a `drop`-related guarantee.
//! Therefore, pinning also comes with a [`drop`]-related guarantee.
//!
//! # `Drop` guarantee
//!
Expand All @@ -139,7 +139,7 @@
//! otherwise invalidating the memory used to store the data is restricted, too.
//! Concretely, for pinned data you have to maintain the invariant
//! that *its memory will not get invalidated or repurposed from the moment it gets pinned until
//! when `drop` is called*. Memory can be invalidated by deallocation, but also by
//! when [`drop`] is called*. Memory can be invalidated by deallocation, but also by
//! replacing a [`Some(v)`] by [`None`], or calling [`Vec::set_len`] to "kill" some elements
//! off of a vector. It can be repurposed by using [`ptr::write`] to overwrite it without
//! calling the destructor first.
Expand All @@ -148,26 +148,27 @@
//! section needs to function correctly.
//!
//! Notice that this guarantee does *not* mean that memory does not leak! It is still
//! completely okay not ever to call `drop` on a pinned element (e.g., you can still
//! call [`mem::forget`] on a `Pin<Box<T>>`). In the example of the doubly-linked
//! completely okay not ever to call [`drop`] on a pinned element (e.g., you can still
//! call [`mem::forget`] on a [`Pin`]`<`[`Box`]`<T>>`). In the example of the doubly-linked
//! list, that element would just stay in the list. However you may not free or reuse the storage
//! *without calling `drop`*.
//! *without calling [`drop`]*.
//!
//! # `Drop` implementation
//!
//! If your type uses pinning (such as the two examples above), you have to be careful
//! when implementing `Drop`. The `drop` function takes `&mut self`, but this
//! when implementing [`Drop`]. The [`drop`] function takes `&mut self`, but this
//! is called *even if your type was previously pinned*! It is as if the
//! compiler automatically called `get_unchecked_mut`.
//! compiler automatically called [`Pin::get_unchecked_mut`].
//!
//! This can never cause a problem in safe code because implementing a type that
//! relies on pinning requires unsafe code, but be aware that deciding to make
//! use of pinning in your type (for example by implementing some operation on
//! `Pin<&Self>` or `Pin<&mut Self>`) has consequences for your `Drop`
//! [`Pin`]`<&Self>` or [`Pin`]`<&mut Self>`) has consequences for your [`Drop`]
//! implementation as well: if an element of your type could have been pinned,
//! you must treat Drop as implicitly taking `Pin<&mut Self>`.
//! you must treat [`Drop`] as implicitly taking [`Pin`]`<&mut Self>`.
//!
//! For example, you could implement `Drop` as follows:
//!
//! ```rust,no_run
//! # use std::pin::Pin;
//! # struct Type { }
Expand All @@ -182,7 +183,8 @@
//! }
//! }
//! ```
//! The function `inner_drop` has the type that `drop` *should* have, so this makes sure that
//!
//! The function `inner_drop` has the type that [`drop`] *should* have, so this makes sure that
//! you do not accidentally use `self`/`this` in a way that is in conflict with pinning.
//!
//! Moreover, if your type is `#[repr(packed)]`, the compiler will automatically
Expand All @@ -192,18 +194,18 @@
//! # Projections and Structural Pinning
//!
//! When working with pinned structs, the question arises how one can access the
//! fields of that struct in a method that takes just `Pin<&mut Struct>`.
//! fields of that struct in a method that takes just [`Pin`]`<&mut Struct>`.
//! The usual approach is to write helper methods (so called *projections*)
//! that turn `Pin<&mut Struct>` into a reference to the field, but what
//! type should that reference have? Is it `Pin<&mut Field>` or `&mut Field`?
//! that turn [`Pin`]`<&mut Struct>` into a reference to the field, but what
//! type should that reference have? Is it [`Pin`]`<&mut Field>` or `&mut Field`?
//! The same question arises with the fields of an `enum`, and also when considering
//! container/wrapper types such as [`Vec<T>`], [`Box<T>`], or [`RefCell<T>`].
//! (This question applies to both mutable and shared references, we just
//! use the more common case of mutable references here for illustration.)
//!
//! It turns out that it is actually up to the author of the data structure
//! to decide whether the pinned projection for a particular field turns
//! `Pin<&mut Struct>` into `Pin<&mut Field>` or `&mut Field`. There are some
//! [`Pin`]`<&mut Struct>` into [`Pin`]`<&mut Field>` or `&mut Field`. There are some
//! constraints though, and the most important constraint is *consistency*:
//! every field can be *either* projected to a pinned reference, *or* have
//! pinning removed as part of the projection. If both are done for the same field,
Expand All @@ -218,12 +220,13 @@
//! ## Pinning *is not* structural for `field`
//!
//! It may seem counter-intuitive that the field of a pinned struct might not be pinned,
//! but that is actually the easiest choice: if a `Pin<&mut Field>` is never created,
//! but that is actually the easiest choice: if a [`Pin`]`<&mut Field>` is never created,
//! nothing can go wrong! So, if you decide that some field does not have structural pinning,
//! all you have to ensure is that you never create a pinned reference to that field.
//!
//! Fields without structural pinning may have a projection method that turns
//! `Pin<&mut Struct>` into `&mut Field`:
//! [`Pin`]`<&mut Struct>` into `&mut Field`:
//!
//! ```rust,no_run
//! # use std::pin::Pin;
//! # type Field = i32;
Expand All @@ -237,16 +240,17 @@
//! ```
//!
//! You may also `impl Unpin for Struct` *even if* the type of `field`
//! is not `Unpin`. What that type thinks about pinning is not relevant
//! when no `Pin<&mut Field>` is ever created.
//! is not [`Unpin`]. What that type thinks about pinning is not relevant
//! when no [`Pin`]`<&mut Field>` is ever created.
//!
//! ## Pinning *is* structural for `field`
//!
//! The other option is to decide that pinning is "structural" for `field`,
//! meaning that if the struct is pinned then so is the field.
//!
//! This allows writing a projection that creates a `Pin<&mut Field>`, thus
//! This allows writing a projection that creates a [`Pin`]`<&mut Field>`, thus
//! witnessing that the field is pinned:
//!
//! ```rust,no_run
//! # use std::pin::Pin;
//! # type Field = i32;
Expand All @@ -262,30 +266,30 @@
//! However, structural pinning comes with a few extra requirements:
//!
//! 1. The struct must only be [`Unpin`] if all the structural fields are
//! `Unpin`. This is the default, but `Unpin` is a safe trait, so as the author of
//! [`Unpin`]. This is the default, but [`Unpin`] is a safe trait, so as the author of
//! the struct it is your responsibility *not* to add something like
//! `impl<T> Unpin for Struct<T>`. (Notice that adding a projection operation
//! requires unsafe code, so the fact that `Unpin` is a safe trait does not break
//! requires unsafe code, so the fact that [`Unpin`] is a safe trait does not break
//! the principle that you only have to worry about any of this if you use `unsafe`.)
//! 2. The destructor of the struct must not move structural fields out of its argument. This
//! is the exact point that was raised in the [previous section][drop-impl]: `drop` takes
//! `&mut self`, but the struct (and hence its fields) might have been pinned before.
//! You have to guarantee that you do not move a field inside your `Drop` implementation.
//! You have to guarantee that you do not move a field inside your [`Drop`] implementation.
//! In particular, as explained previously, this means that your struct must *not*
//! be `#[repr(packed)]`.
//! See that section for how to write `drop` in a way that the compiler can help you
//! See that section for how to write [`drop`] in a way that the compiler can help you
//! not accidentally break pinning.
//! 3. You must make sure that you uphold the [`Drop` guarantee][drop-guarantee]:
//! once your struct is pinned, the memory that contains the
//! content is not overwritten or deallocated without calling the content's destructors.
//! This can be tricky, as witnessed by [`VecDeque<T>`]: the destructor of `VecDeque<T>`
//! can fail to call `drop` on all elements if one of the destructors panics. This violates the
//! `Drop` guarantee, because it can lead to elements being deallocated without
//! their destructor being called. (`VecDeque` has no pinning projections, so this
//! This can be tricky, as witnessed by [`VecDeque<T>`]: the destructor of [`VecDeque<T>`]
//! can fail to call [`drop`] on all elements if one of the destructors panics. This violates
//! the [`Drop`] guarantee, because it can lead to elements being deallocated without
//! their destructor being called. ([`VecDeque<T>`] has no pinning projections, so this
//! does not cause unsoundness.)
//! 4. You must not offer any other operations that could lead to data being moved out of
//! the structural fields when your type is pinned. For example, if the struct contains an
//! `Option<T>` and there is a `take`-like operation with type
//! [`Option<T>`] and there is a `take`-like operation with type
//! `fn(Pin<&mut Struct<T>>) -> Option<T>`,
//! that operation can be used to move a `T` out of a pinned `Struct<T>` -- which means
//! pinning cannot be structural for the field holding this data.
Expand All @@ -301,37 +305,39 @@
//! let content = &mut *b; // And here we have `&mut T` to the same data.
//! }
//! ```
//! This is catastrophic, it means we can first pin the content of the `RefCell<T>`
//! This is catastrophic, it means we can first pin the content of the [`RefCell<T>`]
//! (using `RefCell::get_pin_mut`) and then move that content using the mutable
//! reference we got later.
//!
//! ## Examples
//!
//! For a type like [`Vec<T>`], both possibilites (structural pinning or not) make sense.
//! A `Vec<T>` with structural pinning could have `get_pin`/`get_pin_mut` methods to get
//! A [`Vec<T>`] with structural pinning could have `get_pin`/`get_pin_mut` methods to get
//! pinned references to elements. However, it could *not* allow calling
//! `pop` on a pinned `Vec<T>` because that would move the (structurally pinned) contents!
//! Nor could it allow `push`, which might reallocate and thus also move the contents.
//! A `Vec<T>` without structural pinning could `impl<T> Unpin for Vec<T>`, because the contents
//! are never pinned and the `Vec<T>` itself is fine with being moved as well.
//! [`pop`][Vec::pop] on a pinned [`Vec<T>`] because that would move the (structurally pinned)
//! contents! Nor could it allow [`push`][Vec::push], which might reallocate and thus also move the
//! contents.
//!
//! A [`Vec<T>`] without structural pinning could `impl<T> Unpin for Vec<T>`, because the contents
//! are never pinned and the [`Vec<T>`] itself is fine with being moved as well.
//! At that point pinning just has no effect on the vector at all.
//!
//! In the standard library, pointer types generally do not have structural pinning,
//! and thus they do not offer pinning projections. This is why `Box<T>: Unpin` holds for all `T`.
//! It makes sense to do this for pointer types, because moving the `Box<T>`
//! does not actually move the `T`: the `Box<T>` can be freely movable (aka `Unpin`) even if the `T`
//! is not. In fact, even `Pin<Box<T>>` and `Pin<&mut T>` are always `Unpin` themselves,
//! for the same reason: their contents (the `T`) are pinned, but the pointers themselves
//! can be moved without moving the pinned data. For both `Box<T>` and `Pin<Box<T>>`,
//! whether the content is pinned is entirely independent of whether the pointer is
//! pinned, meaning pinning is *not* structural.
//! does not actually move the `T`: the [`Box<T>`] can be freely movable (aka `Unpin`) even if
//! the `T` is not. In fact, even [`Pin`]`<`[`Box`]`<T>>` and [`Pin`]`<&mut T>` are always
//! [`Unpin`] themselves, for the same reason: their contents (the `T`) are pinned, but the
//! pointers themselves can be moved without moving the pinned data. For both [`Box<T>`] and
//! [`Pin`]`<`[`Box`]`<T>>`, whether the content is pinned is entirely independent of whether the
//! pointer is pinned, meaning pinning is *not* structural.
//!
//! When implementing a [`Future`] combinator, you will usually need structural pinning
//! for the nested futures, as you need to get pinned references to them to call `poll`.
//! for the nested futures, as you need to get pinned references to them to call [`poll`].
//! But if your combinator contains any other data that does not need to be pinned,
//! you can make those fields not structural and hence freely access them with a
//! mutable reference even when you just have `Pin<&mut Self>` (such as in your own
//! `poll` implementation).
//! mutable reference even when you just have [`Pin`]`<&mut Self>` (such as in your own
//! [`poll`] implementation).
//!
//! [`Pin<P>`]: struct.Pin.html
//! [`Unpin`]: ../marker/trait.Unpin.html
Expand All @@ -342,6 +348,16 @@
//! [`Box<T>`]: ../../std/boxed/struct.Box.html
//! [`Vec<T>`]: ../../std/vec/struct.Vec.html
//! [`Vec::set_len`]: ../../std/vec/struct.Vec.html#method.set_len
//! [`Pin`]: struct.Pin.html
//! [`Box`]: ../../std/boxed/struct.Box.html
//! [Vec::pop]: ../../std/vec/struct.Vec.html#method.pop
//! [Vec::push]: ../../std/vec/struct.Vec.html#method.push
//! [`Rc`]: ../../std/rc/struct.Rc.html
//! [`RefCell<T>`]: ../../std/cell/struct.RefCell.html
//! [`Drop`]: ../../std/ops/trait.Drop.html
//! [`drop`]: ../../std/ops/trait.Drop.html#tymethod.drop
//! [`VecDeque<T>`]: ../../std/collections/struct.VecDeque.html
//! [`Option<T>`]: ../../std/option/enum.Option.html
//! [`VecDeque<T>`]: ../../std/collections/struct.VecDeque.html
//! [`RefCell<T>`]: ../cell/struct.RefCell.html
//! [`None`]: ../option/enum.Option.html#variant.None
Expand All @@ -350,6 +366,8 @@
//! [`Future`]: ../future/trait.Future.html
//! [drop-impl]: #drop-implementation
//! [drop-guarantee]: #drop-guarantee
//! [`poll`]: ../../std/future/trait.Future.html#tymethod.poll
//! [`Pin::get_unchecked_mut`]: struct.Pin.html#method.get_unchecked_mut

#![stable(feature = "pin", since = "1.33.0")]

Expand Down