From 373844c9964c747e5851af4bc40e18f202ec9a2a Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 21 Sep 2024 06:40:59 -0700 Subject: [PATCH 1/3] Add tracking issue for static-mut-references --- src/rust-2024/static-mut-references.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rust-2024/static-mut-references.md b/src/rust-2024/static-mut-references.md index 2b9e9d1d..c6f5e4a8 100644 --- a/src/rust-2024/static-mut-references.md +++ b/src/rust-2024/static-mut-references.md @@ -1,6 +1,7 @@ # Disallow references to static mut 🚧 The 2024 Edition has not yet been released and hence this section is still "under construction". +More information may be found in the tracking issue at . ## Summary From ef987b4737480eb8fe5c64da113767e2ed536424 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 21 Sep 2024 09:00:55 -0700 Subject: [PATCH 2/3] Update static-mut-refs now that it is just a lint Updates for the changes from https://github.com/rust-lang/rust/pull/124895 --- src/rust-2024/static-mut-references.md | 30 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/rust-2024/static-mut-references.md b/src/rust-2024/static-mut-references.md index c6f5e4a8..a05d266d 100644 --- a/src/rust-2024/static-mut-references.md +++ b/src/rust-2024/static-mut-references.md @@ -5,29 +5,41 @@ More information may be found in the tracking issue at + ```rust static mut X: i32 = 23; static mut Y: i32 = 24; unsafe { - let y = &X; // ERROR: reference of mutable static - let ref x = X; // ERROR: reference of mutable static - let (x, y) = (&X, &Y); // ERROR: reference of mutable static + let y = &X; // ERROR: shared reference to mutable static + let ref x = X; // ERROR: shared reference to mutable static + let (x, y) = (&X, &Y); // ERROR: shared reference to mutable static } ``` Merely taking such a reference in violation of Rust's mutability XOR aliasing requirement has always been *instantaneous* [undefined behavior], **even if the reference is never read from or written to**. Furthermore, upholding mutability XOR aliasing for a `static mut` requires *reasoning about your code globally*, which can be particularly difficult in the face of reentrancy and/or multithreading. +Note that there are some cases where implicit references are automatically created without a visible `&` operator. For example, these situations will also trigger the lint: + + +```rust +static mut NUMS: &[u8; 3] = &[0, 1, 2]; + +unsafe { + println!("{NUMS:?}"); // ERROR: shared reference to mutable static + let n = NUMS.len(); // ERROR: shared reference to mutable static +} +``` + ## Alternatives Wherever possible, it is **strongly recommended** to use instead an *immutable* `static` of a type that provides *interior mutability* behind some *locally-reasoned abstraction* (which greatly reduces the complexity of ensuring that Rust's mutability XOR aliasing requirement is upheld). @@ -40,6 +52,4 @@ In situations where no locally-reasoned abstraction is possible and you are ther ## Migration -🚧 The automatic migration for this has not yet been implemented. - - +There is no automatic migration to fix these references to `static mut`. To avoid undefined behavior you must rewrite your code to use a different approach as recommended in the [Alternatives](#alternatives) section. From 0c3adde38da9f5e72d7139fe3dd064517e49847a Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 21 Sep 2024 09:04:51 -0700 Subject: [PATCH 3/3] Switch addr_of_mut for raw borrow operators Now that there is explicit syntax for this, let's use it. --- src/rust-2024/static-mut-references.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rust-2024/static-mut-references.md b/src/rust-2024/static-mut-references.md index a05d266d..01b61b46 100644 --- a/src/rust-2024/static-mut-references.md +++ b/src/rust-2024/static-mut-references.md @@ -44,11 +44,12 @@ unsafe { Wherever possible, it is **strongly recommended** to use instead an *immutable* `static` of a type that provides *interior mutability* behind some *locally-reasoned abstraction* (which greatly reduces the complexity of ensuring that Rust's mutability XOR aliasing requirement is upheld). -In situations where no locally-reasoned abstraction is possible and you are therefore compelled still to reason globally about accesses to your `static` variable, you must now use raw pointers such as can be obtained via the [`addr_of_mut!`] macro. By first obtaining a raw pointer rather than directly taking a reference, (the safety requirements of) accesses through that pointer will be more familiar to `unsafe` developers and can be deferred until/limited to smaller regions of code. +In situations where no locally-reasoned abstraction is possible and you are therefore compelled still to reason globally about accesses to your `static` variable, you must now use raw pointers such as can be obtained via the [`&raw const` or `&raw mut` operators][raw]. By first obtaining a raw pointer rather than directly taking a reference, (the safety requirements of) accesses through that pointer will be more familiar to `unsafe` developers and can be deferred until/limited to smaller regions of code. [Undefined Behavior]: ../../reference/behavior-considered-undefined.html [`static mut`]: ../../reference/items/static-items.html#mutable-statics [`addr_of_mut!`]: https://docs.rust-lang.org/core/ptr/macro.addr_of_mut.html +[raw]: ../../reference/expressions/operator-expr.html#raw-borrow-operators ## Migration