about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlexis Bourget <alexis.bourget@gmail.com>2020-06-28 20:20:32 +0200
committerAlexis Bourget <alexis.bourget@gmail.com>2020-06-28 20:20:32 +0200
commitdfd454bd3843c4f4dee2e943297bf3d208252dc6 (patch)
treecaa9e6afc5b7dd898fd9ba0ba0ed3909134b419e /src/libstd
parent2bbc2b3de42f3b14ccc8b62c2acffc8840177777 (diff)
downloadrust-dfd454bd3843c4f4dee2e943297bf3d208252dc6.tar.gz
rust-dfd454bd3843c4f4dee2e943297bf3d208252dc6.zip
Apply suggestions, reformulating some paragraphs and improving some examples
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/keyword_docs.rs74
1 files changed, 36 insertions, 38 deletions
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index 746165beab8..d84ed1c93de 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -1030,22 +1030,39 @@ mod self_upper_keyword {}
 //
 /// A place that is valid for the duration of a program.
 ///
-/// A `static` item is similar to a [`const`] item in that it lives for the
-/// entire duration of the program and need to have its type explicited, with a
-/// `static` lifetime, outliving any other lifetime. Added to that, `static`
-/// items represent a precise memory location.
+/// A static item is a value which is valid for the entire duration of your
+/// program (a `'static` lifetime).
+///
+/// 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:
+///
+/// ```rust,compile_fail,E0507
+/// static VEC: Vec<u32> = vec![];
+///
+/// fn move_vec(v: Vec<u32>) -> Vec<u32> {
+///     v
+/// }
+///
+/// move_vec(VEC);
+/// ```
+///
 /// # Simple `static`s
 ///
-/// Non-[`mut`] `static` items that contain a type that is not interior mutable
-/// may be placed in read-only memory. All access to a `static` item are
-/// considered safe but some restrictions apply. See the [Reference] for more
-/// information.
+/// 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];
@@ -1054,43 +1071,22 @@ mod self_upper_keyword {}
 /// let r2 = &FOO as *const _;
 /// // With a strictly read-only static, references will have the same adress
 /// assert_eq!(r1, r2);
+/// // A static item is used just like a variable
+/// 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. To make concurrency bugs hard to run into,
-/// all access to a `static mut` require an [`unsafe`] block. Care should be
-/// taken to ensure access (both read and write) are thread-safe.
+/// 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 very useful: they can be used
-/// to represent global state shared by the whole program or be used in
+/// 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.
 ///
-/// As global state:
-///
-/// ```rust
-/// # #![allow(unused_variables)]
-/// # fn main() {}
-/// # fn atomic_add(_: &mut u32, _: u32) -> u32 { 2 }
-/// static mut LEVELS: u32 = 0;
-///
-/// // This violates the idea of no shared state, and this doesn't internally
-/// // protect against races, so this function is `unsafe`
-/// unsafe fn bump_levels_unsafe1() -> u32 {
-///     let ret = LEVELS;
-///     LEVELS += 1;
-///     return ret;
-/// }
-///
-/// // Assuming that we have an atomic_add function which returns the old value,
-/// // this function is "safe" but the meaning of the return value may not be
-/// // what callers expect, so it's still marked as `unsafe`
-/// unsafe fn bump_levels_unsafe2() -> u32 {
-///     return atomic_add(&mut LEVELS, 1);
-/// }
-/// ```
-///
 /// In an [`extern`] block:
 ///
 /// ```rust,no_run
@@ -1108,7 +1104,9 @@ mod self_upper_keyword {}
 /// [`mut`]: keyword.mut.html
 /// [`unsafe`]: keyword.unsafe.html
 /// [`drop`]: mem/fn.drop.html
-/// [Reference]: ../reference/items/static-items.html#static-items
+/// [`Sync`]: marker/trait.Sync.html
+/// [`RefCell`]: cell/struct.RefCell.html
+/// [Reference]: ../reference/items/static-items.html
 mod static_keyword {}
 
 #[doc(keyword = "struct")]