Posted by ravenical 1/1/2026
I think fighting the borrow checker is more like a rite of passage. Rust is not my favorite language but the borrow checker is great.
Multiple mutable borrows do not need multiple threads to cause UB. Consider the following:
fn main() {
let mut v = vec![0, 1, 2];
let e = &mut v[0];
v.push(3);
*e = 4;
}
rustc refuses to compile this code due to multiple mutable borrows of `v` [0]: error[E0499]: cannot borrow `v` as mutable more than once at a time
--> <source>:4:5
|
3 | let e = &mut v[0];
| - first mutable borrow occurs here
4 | v.push(3);
| ^ second mutable borrow occurs here
5 | *e = 4;
| ------ first borrow later used here
If rustc allowed multiple mutable borrows here, `v.push(3)` would cause the underlying vec to reallocate, which invalidates `e`, and so `*e = 4` would cause UB.The two main things the compiler allows in an unsafe block but not elsewhere are calling other code marked "unsafe" and dereferencing raw pointers. The net result is that safe code running in a system that's not exhibiting undefined behaviour is defined to continue to not exhibit undefined behaviour, but the compiler is unable in general to prove that an unsafe block won't trigger undefined behaviour.
You can side-step the borrow checker by using pointers instead of references, but using that power to construct an invalid reference is undefined behaviour.