unsafe code

As I said before, unsafe code isn't inherently bad, it's just code that comes with a contract. Keeping this in mind helped me get over my initial apprehension about using unsafe code.

If you write concurrent code, I think unsafe code is inevitable. There's just too much to do with raw pointers and memory. Additionally, there are many more contracts the compiler can't enforce in multithreaded scenarios.

Philosophically, concurrent code has to deal with shared mutable state, otherwise it wouldn't do anything useful. Shared mutable state is inherently unsafe! That's why Rust only allows one mutable reference (&mut) at a time: it prevents memory bugs like data races. Thus, there is some danger intrinsically associated with writing low-level concurrent code.

"Shared mutable state is, among other things, the root of all evil" - Me, 2022

Although it seems scary at first, I'm really glad Rust has the concept of unsafe. Whenever I had any memory bugs, I knew that the root cause must have been in an unsafe block. Systematically checking over those blocks allowed me to fix my code quickly.

It's good that we have to make explicit where we are doing potentially unsafe things. Not just because of debugging, but because it makes us pause and check everything over one more time. If nothing was unsafe, or everything was unsafe, reasoning about our code would be much harder in my opinion.

A note on debugging: always read the safety contract and document why what you're doing is safe! I caught so many bugs just by going over the safety contract again and realizing I wasn't following it.