Rust does make compromises of performance. That is not always bad so long as the compromises are minor. Fortunately Rust can do most of the checking at compile time, but it if you read from an empty vector Rust doesn't have undefined behavior and that means there is a runtime check of some sort in at least some cases.
The trick is to find the right place to compromise so the cost is minimal overall even if it isn't zero.
The thing is, although the check looks like work, a correct C++ solution almost always needs to do the same work. There are real world cases where it doesn't, but lots more where in C++ we need to explicitly do the work or our program malfunctions, sometimes in subtle ways - while in Rust we get this right by default.
There are cases where you as the programmer have enough to know that there is data in the container even though anything less than whole program analysis cannot prove it. Rust will do unneeded check in those cases.
I do agree though, the cost of the check is so small that it doesn't matter in most cases.
Dropping to unsafe rust is quite easy as long as you understand what you're doing (and reading pointer is generally unsafe).
In the case of automatically upgrading from int to bignum, or green threads, going lower level would be much harder.
I just wish Rust stayed focused on being the best systems level programming language (for example finishing the SIMD package, getting into stable Rust, getting language level GPU integration similar to CUDA / OpenCL).
PyToch, and now the newer GGML for example is still written in C++ for example
I still like the changes being made in the language, just not the focus.
Rust also gives you choices. If, for whatever reason, you need to get rid of that runtime check, you can always use `unsafe`. Safety is the happy path, but you aren't locked in.
The trick is to find the right place to compromise so the cost is minimal overall even if it isn't zero.