> True. But I would not expect any programming language to do that.
Haskell (and its more research-y brethren) do exactly this. You mark your functions with IO to do IO, or nothing for a pure function.
Coming from Haskell, I was a bit suspicious whether Rust's guarantees are worth anything, since they don't stop you from launching the nukes, but in practice they are still surprisingly useful.
Btw, I think D has an option to mark your functions as 'pure'. Pure functions are allowed internal mutation, but not side effects. This is much more useful than C++'s const. (You can tell that D, just like Rust, was designed by people who set out to avoid and improve on C++'s mistakes.)