@@ -1030,22 +1030,39 @@ mod self_upper_keyword {}
1030
1030
//
1031
1031
/// A place that is valid for the duration of a program.
1032
1032
///
1033
- /// A `static` item is similar to a [`const`] item in that it lives for the
1034
- /// entire duration of the program and need to have its type explicited, with a
1035
- /// `static` lifetime, outliving any other lifetime. Added to that, `static`
1036
- /// items represent a precise memory location.
1033
+ /// A static item is a value which is valid for the entire duration of your
1034
+ /// program (a `'static` lifetime).
1035
+ ///
1036
+ /// On the surface, `static` items seem very similar to [`const`]s: both contain
1037
+ /// a value, both require type annotations and both can only be initialized with
1038
+ /// constant functions and values. However, `static`s are notably different in
1039
+ /// that they represent a location in memory. That means that you can have
1040
+ /// references to `static` items and potentially even modify them, making them
1041
+ /// essentially global variables.
1037
1042
///
1038
1043
/// Static items do not call [`drop`] at the end of the program.
1039
1044
///
1040
1045
/// There are two types of `static` items: those declared in association with
1041
1046
/// the [`mut`] keyword and those without.
1042
1047
///
1048
+ /// Items that are both static and owned cannot be moved:
1049
+ ///
1050
+ /// ```rust,compile_fail,E0507
1051
+ /// static VEC: Vec<u32> = vec![];
1052
+ ///
1053
+ /// fn move_vec(v: Vec<u32>) -> Vec<u32> {
1054
+ /// v
1055
+ /// }
1056
+ ///
1057
+ /// move_vec(VEC);
1058
+ /// ```
1059
+ ///
1043
1060
/// # Simple `static`s
1044
1061
///
1045
- /// Non -[`mut`] `static` items that contain a type that is not interior mutable
1046
- /// may be placed in read-only memory. All access to a `static` item are
1047
- /// considered safe but some restrictions apply. See the [Reference] for more
1048
- /// information.
1062
+ /// Accessing non -[`mut`] `static` items is considered safe, but some
1063
+ /// restrictions apply. Most notably, the type of a `static` value needs to
1064
+ /// implement the [`Sync`] trait, ruling out interior mutability containers
1065
+ /// like [`RefCell`]. See the [Reference] for more information.
1049
1066
///
1050
1067
/// ```rust
1051
1068
/// static FOO: [i32; 5] = [1, 2, 3, 4, 5];
@@ -1054,43 +1071,22 @@ mod self_upper_keyword {}
1054
1071
/// let r2 = &FOO as *const _;
1055
1072
/// // With a strictly read-only static, references will have the same adress
1056
1073
/// assert_eq!(r1, r2);
1074
+ /// // A static item is used just like a variable
1075
+ /// println!("{:?}", FOO);
1057
1076
/// ```
1058
1077
///
1059
1078
/// # Mutable `static`s
1060
1079
///
1061
1080
/// If a `static` item is declared with the [`mut`] keyword, then it is allowed
1062
- /// to be modified by the program. To make concurrency bugs hard to run into,
1063
- /// all access to a `static mut` require an [`unsafe`] block. Care should be
1064
- /// taken to ensure access (both read and write) are thread-safe.
1081
+ /// to be modified by the program. However, accessing mutable `static`s can
1082
+ /// cause undefined behavior in a number of ways, for example due to data races
1083
+ /// in a multithreaded context. As such, all accesses to mutable `static`s
1084
+ /// require an [`unsafe`] block.
1065
1085
///
1066
- /// Despite their unsafety, mutable `static`s are very useful: they can be used
1067
- /// to represent global state shared by the whole program or be used in
1086
+ /// Despite their unsafety, mutable `static`s are necessary in many contexts:
1087
+ /// they can be used to represent global state shared by the whole program or in
1068
1088
/// [`extern`] blocks to bind to variables from C libraries.
1069
1089
///
1070
- /// As global state:
1071
- ///
1072
- /// ```rust
1073
- /// # #![allow(unused_variables)]
1074
- /// # fn main() {}
1075
- /// # fn atomic_add(_: &mut u32, _: u32) -> u32 { 2 }
1076
- /// static mut LEVELS: u32 = 0;
1077
- ///
1078
- /// // This violates the idea of no shared state, and this doesn't internally
1079
- /// // protect against races, so this function is `unsafe`
1080
- /// unsafe fn bump_levels_unsafe1() -> u32 {
1081
- /// let ret = LEVELS;
1082
- /// LEVELS += 1;
1083
- /// return ret;
1084
- /// }
1085
- ///
1086
- /// // Assuming that we have an atomic_add function which returns the old value,
1087
- /// // this function is "safe" but the meaning of the return value may not be
1088
- /// // what callers expect, so it's still marked as `unsafe`
1089
- /// unsafe fn bump_levels_unsafe2() -> u32 {
1090
- /// return atomic_add(&mut LEVELS, 1);
1091
- /// }
1092
- /// ```
1093
- ///
1094
1090
/// In an [`extern`] block:
1095
1091
///
1096
1092
/// ```rust,no_run
@@ -1108,7 +1104,9 @@ mod self_upper_keyword {}
1108
1104
/// [`mut`]: keyword.mut.html
1109
1105
/// [`unsafe`]: keyword.unsafe.html
1110
1106
/// [`drop`]: mem/fn.drop.html
1111
- /// [Reference]: ../reference/items/static-items.html#static-items
1107
+ /// [`Sync`]: marker/trait.Sync.html
1108
+ /// [`RefCell`]: cell/struct.RefCell.html
1109
+ /// [Reference]: ../reference/items/static-items.html
1112
1110
mod static_keyword { }
1113
1111
1114
1112
#[ doc( keyword = "struct" ) ]
0 commit comments