The crucial trick in Rust is
not that the index operations are bounds checked, that's easy, as you observed plenty of C++ toolchains can do that.
The crucial trick is providing the unchecked operations (with improved performance) as unergonomic alternatives. *(five.get_unchecked_mut(20)) = k; // looks horrible. Nobody wants to write that, so when they don't need it they won't write it. The fact calling get_unchecked_mut requires unsafe is part of how Rust could achieve its goals, but the choice to not make this ergonomic is why it actually delivers in practice.
What CppFront wants here, and P2687 proposes, and lots of other C++ work has suggested, is roughly:
[[suppress(bounds_check)]] { five[20] = k; }
Thus imitating what they
think Rust does here, rather than what it actually did, and in the process completely missing the point.