> Unless you're talking to hardware or another language, you should not need unsafe code.
... or if you're implementing safe abstractions on top of data structures or synchronization protocols that the type system cannot automatically infer to be safe.
Of course that is going to be a smallish subset of Rust programmers that gets smaller with time as the standard library fills out, but an important one!
For those who aren't as familiar with Rust, the std::sync [0] module can be a fun way to cut your teeth.
For example, here's the implementation of Mutex.lock [1]:
pub fn lock(&self) -> LockResult<MutexGuard<T>> {
unsafe { self.inner.lock.lock() }
MutexGuard::new(&*self.inner, &self.data)
}
Note that the self argument is immutable: "&self" instead of "&mut self". This may seem odd: doesn't locking a mutex
require a change to its innards? Which is why you should not be surprised to see the unsafe, which allows us to bend the immutability of &self in order to acquire the lock.
In fact, how could it be otherwise? Rust prevents there ever being more than one &mut to something, so if the signature of Mutex::lock was "&mut self", there could only ever be one usable ref to the Mutex! That would be pointless, of course -- multiple threads need to have references to the mutex.
We're still safe, though, because the "mut-aliasing" that Rust normally prevents via the borrow checker at compile time is being replaced with a run-time mechanism that achieves the same thing via the Mutex and the MutexGuard [2].
[0] http://doc.rust-lang.org/std/sync/index.html
[1] http://doc.rust-lang.org/src/std/sync/mutex.rs.html#196-211
[2] Well, strictly speaking a RwLock is a closer runtime approximation to the borrow checker's rules, because it allows multiple simultaneous readers: http://doc.rust-lang.org/std/sync/struct.RwLock.html