The borrow checker does not prevent out of bounds access of arrays (or vectors or whatever you want to call them).
The borrow checker is intended to protect against "temporal memory unsafety". It can tell you that you are using something that has already been freed, or something that could be freed while you are using it for example.
Bounds checking is a "spatial memory unsafety" problem, it has nothing to do with borrowing and exclusive references.
Bounds checking is a trivial problem, for an array that has N length, like a char[N], something tried to access a value past the end of the array (like char[11] if N=10).
Rust doesn't really do anything special here and protecting against buffer overflows does not require any novel technology.
An implementation of bounds checking is as simple as an "assert(I >= 0 && I < N)", where I is the index and N is the length of the array.
In C this is difficult to do because arrays or are just pointers (or decay to) and pointers do not carry any information about the length. Keeping a separate variable containing the length around but this apparently is too unergonomic since virtually all C software does not check every array access in all parts of the program.
In Rust, its very rare to use raw pointers to work with "arrays". Instead there is a "slice" type that models the concept of a contiguous sequence of values in memory. The important part is that the slice type is a "fat pointer", and the fat pointer contains the length or the array. The slice type is able to check every access in all parts of program.
So all slice accesses are checked by default. and you can't "turn it off". If you really want to disable bounds checking for some reason, there is an unsafe "get_unchecked" function.
There are some sequence types other than slices, arrays for example (array is a specific type here). They are still checked but they don't have to store the length information because it's encoded into it's type.
The Vec type is another one. It is a resizable "array", and it stores 3 things, a pointer to the allocation, the capacity and the length. That's mostly not relevant here though. It checks every access like the other types.
Bounds checking is a very easily preventable error. It should not be happening in $CURRENT_YEAR.
The borrow checker is intended to protect against "temporal memory unsafety". It can tell you that you are using something that has already been freed, or something that could be freed while you are using it for example.
Bounds checking is a "spatial memory unsafety" problem, it has nothing to do with borrowing and exclusive references.
Bounds checking is a trivial problem, for an array that has N length, like a char[N], something tried to access a value past the end of the array (like char[11] if N=10).
Rust doesn't really do anything special here and protecting against buffer overflows does not require any novel technology.
An implementation of bounds checking is as simple as an "assert(I >= 0 && I < N)", where I is the index and N is the length of the array.
In C this is difficult to do because arrays or are just pointers (or decay to) and pointers do not carry any information about the length. Keeping a separate variable containing the length around but this apparently is too unergonomic since virtually all C software does not check every array access in all parts of the program.
In Rust, its very rare to use raw pointers to work with "arrays". Instead there is a "slice" type that models the concept of a contiguous sequence of values in memory. The important part is that the slice type is a "fat pointer", and the fat pointer contains the length or the array. The slice type is able to check every access in all parts of program.
So all slice accesses are checked by default. and you can't "turn it off". If you really want to disable bounds checking for some reason, there is an unsafe "get_unchecked" function.
There are some sequence types other than slices, arrays for example (array is a specific type here). They are still checked but they don't have to store the length information because it's encoded into it's type.
The Vec type is another one. It is a resizable "array", and it stores 3 things, a pointer to the allocation, the capacity and the length. That's mostly not relevant here though. It checks every access like the other types.
Bounds checking is a very easily preventable error. It should not be happening in $CURRENT_YEAR.