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

Document the static keyword #73716

Merged
merged 3 commits into from
Jul 1, 2020
Merged
Changes from 2 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
78 changes: 76 additions & 2 deletions src/libstd/keyword_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1030,9 +1030,83 @@ mod self_upper_keyword {}
//
/// A place that is valid for the duration of a program.
///
/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
/// A static item is a value which is valid for the entire duration of your
/// program (a `'static` lifetime).
poliorcetics marked this conversation as resolved.
Show resolved Hide resolved
///
/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
/// On the surface, `static` items seem very similar to [`const`]s: both contain
/// a value, both require type annotations and both can only be initialized with
/// constant functions and values. However, `static`s are notably different in
/// that they represent a location in memory. That means that you can have
/// references to `static` items and potentially even modify them, making them
/// essentially global variables.
///
/// Static items do not call [`drop`] at the end of the program.
///
/// There are two types of `static` items: those declared in association with
/// the [`mut`] keyword and those without.
///
/// Items that are both static and owned cannot be moved:
poliorcetics marked this conversation as resolved.
Show resolved Hide resolved
///
/// ```rust,compile_fail,E0507
/// static VEC: Vec<u32> = vec![];
///
/// fn move_vec(v: Vec<u32>) -> Vec<u32> {
/// v
/// }
///
/// move_vec(VEC);
poliorcetics marked this conversation as resolved.
Show resolved Hide resolved
/// ```
///
/// # Simple `static`s
///
/// Accessing non-[`mut`] `static` items is considered safe, but some
/// restrictions apply. Most notably, the type of a `static` value needs to
/// implement the [`Sync`] trait, ruling out interior mutability containers
/// like [`RefCell`]. See the [Reference] for more information.
///
/// ```rust
/// static FOO: [i32; 5] = [1, 2, 3, 4, 5];
///
/// let r1 = &FOO as *const _;
/// let r2 = &FOO as *const _;
/// // With a strictly read-only static, references will have the same adress
/// assert_eq!(r1, r2);
poliorcetics marked this conversation as resolved.
Show resolved Hide resolved
/// // A static item is used just like a variable
LukasKalbertodt marked this conversation as resolved.
Show resolved Hide resolved
/// println!("{:?}", FOO);
/// ```
///
/// # Mutable `static`s
///
/// If a `static` item is declared with the [`mut`] keyword, then it is allowed
/// to be modified by the program. However, accessing mutable `static`s can
/// cause undefined behavior in a number of ways, for example due to data races
/// in a multithreaded context. As such, all accesses to mutable `static`s
/// require an [`unsafe`] block.
///
/// Despite their unsafety, mutable `static`s are necessary in many contexts:
/// they can be used to represent global state shared by the whole program or in
/// [`extern`] blocks to bind to variables from C libraries.
///
/// In an [`extern`] block:
///
/// ```rust,no_run
/// # #![allow(dead_code)]
/// extern "C" {
/// static mut ERROR_MESSAGE: *mut std::os::raw::c_char;
/// }
/// ```
///
/// Mutable `static`s, just like simple `static`s, have some restrictions that
/// apply to them. See the [Reference] for more information.
///
/// [`const`]: keyword.const.html
/// [`extern`]: keyword.extern.html
/// [`mut`]: keyword.mut.html
/// [`unsafe`]: keyword.unsafe.html
/// [`drop`]: mem/fn.drop.html
/// [`Sync`]: marker/trait.Sync.html
/// [`RefCell`]: cell/struct.RefCell.html
/// [Reference]: ../reference/items/static-items.html
mod static_keyword {}

#[doc(keyword = "struct")]
Expand Down