It is in fact checked by both the compiler and the borrow checker. The only difference between safe and unsafe code is that the latter allows dereference of pointers and direct manipulation of memory, which may result in segfaults, memory leaks and data races.