Post your "static mut" alternative
As you should know, getting a reference (shared or exclusive) to a "static mut" will probably end up as a compile time error in 2024 edition.
Like a lot of people, I use "static mut" for global state. I never really thought about why "static mut" is whacky.
If my program is single thread, why do I need to synchronize the access of a "static mut" ? After all, no race condition can happen.
Why Rust force me to use "unsafe" to touch this "static mut" ?
The reason is aliasing : if you use "static mut" in a way that end up with more than 1 exclusive reference, this is undefined behavior.
The compiler assume only 1 exclusive reference to a memory location can exist at any point in time. "static mut" give you the power to get as many exclusive reference you want (by using "unsafe").
Even if you think you can manage this, this can be very surprising and result in ugly code.
1st, you'll have to use "unsafe" at any time you touch the "static mut".
2nd, if you store an exclusive reference of the "static mut" on the stack (temporary or function argument), you can't have another one unless the first one lifetime end.
3rd, you'll have to shorten the lifetime yourself by using block {} or function call.
4th, even using a shared reference forbid you to have an exclusive reference somewhere.
It's very easy to forgot you have already one reference of the "static mut" in-use inside your call-stack (upper), and the compiler doesn't say anything because all access of the "static mut" are gate behind "unsafe". The same problem happen in multi-thread with Mutex : if you have one lock in your call-stack, and you try to lock the same Mutex again, it's probably a deadlock. One could consider it's a programmer error and you should respect the invariant, I don't know what to say about that.
What are your favorite alternative ? OnceCell, OnceLock. UnsafeCell, SyncUnsafeCell, RefCell, Arc<Mutex>, Rc<RefCell>, std::ptr::addr_of_mut! ?