(0) Automatically and statically, in which case there is an unavoidable tradeoff between the simplicity and the power of the static analyses. Example: non-lexical lifetimes.
(1) Automatically and dynamically, in which case you need performance-draining checks. Example: slice indexing.
(2) Manually, i.e., leave it as an exercise for the programmer, in which case you need a language with a formal semantics, because how else are you supposed to prove anything? Example: none that I know of in Rust or any other similar language.
There are no other options, although you can take a pick and choose approach for different use cases. IMO (2) has not been given the attention it deserves.
---
So, do you have any concrete idea regarding what could be made simpler?