Rust makes it really difficult to share mutable data. But once you do that, such as by smuggling a pointer _through_ an unsafe block, all bets are off, even for code outside an unsafe block.
Also, as with Java there will always be bugs in the compiler and runtime. Rust programs were susceptible to StackClash just as much as C applications.
No matter what language you use, if you minimize shared mutable data you'll minimize thread-safety issues.
That proof might be parameterised by a proof that some external FFI function was safe, which you might not be able to actually prove and have to assume, but then you would have your assumptions well-documented.
As it is, you have to justify the safety of your unsafe blocks to other programmers using comments, which kind of sucks.
Still better than every other fast language in this area though so I can't complain much.