You have that.
For example, if you have contiguous memory, the various forms of the [T] slice type can be used, they don't impose any allocation expectations. (And, once the standard library allows pluggable allocators, you'll likely be able to use Vec directly, for a growable vector type.)
If you don't have contiguous memory, then it's a bit more work, but one can still use features like generics and privacy to spend a few lines building abstractions that bounds check in the right places. It's not like using a proof language to extract a program that is guaranteed to have no out of bounds accesses, or a compiler that some how deduces what the bounds of your data structure is, but the former has its own complexity downsides, and the latter seems infeasible, in general.