Description
static mut
is almost impossible to use correctly, see rust-lang-nursery/lazy-static.rs#117 for an example in the widely-used lazy-static
.
You must be able to show that every borrow of the static mut
is not reentrant (as opposed to regular interior mutability, which only requires reentrance-freedom when accessing data), which is almost entirely impossible in real-world scenarios.
We have a chance at removing it from Rust2018 and force people to use a proper synchronization abstraction (e.g. lazy_static!
+ Mutex
), or in lieu of one, thread_local!
/ scoped_thread_local!
.
If they were using static mut
with custom synchronization logic, they should do this:
pub struct CustomSynchronizingAbstraction<T> {
/* UnsafeCell / Cell / RefCell / etc. around data, e.g. `T` */
}
// Promise that proper synchronization exists *around accesses*.
unsafe impl<T: Sync> Sync for CustomSynchronizingAbstraction<T> {}
And then use CustomSynchronizingAbstraction
with regular static
s, safely.
This matches the "soundness boundary" of Rust APIs, whereas static mut
is more like C.
cc @RalfJung @rust-lang/compiler @rust-lang/lang
2023-08 Note from triage, many years later: there's now https://doc.rust-lang.org/1.71.0/std/cell/struct.SyncUnsafeCell.html in the library, added by #95438, which can be used instead of static mut
. But static mut
is not even soft-deprecated currently.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status