fn func_index(vec: &mut Vec::<usize>) {
for i in 0..vec.len() {
vec[i] = i;
}
}
fn func_iter(vec: &mut Vec::<usize>) {
for (i, el) in vec.iter_mut().enumerate() {
*el = i;
}
}
I assumed that rustc is able to see the equivalence and produce the same assembly code for both (at least in release mode). Unfortunately this is not true:
The problem is that with the mutable pointer to a Vec LLVM assumes you could potentially modify the length while iterating and this prevents it from removing the bound check.
Of course this is not the case, however the specific optimization that rustc can use to tell LLVM it isn't actually the case is currently disabled because sometimes it causes LLVM to miscompile programs. You can enable it anyway with the flag -Zmutable-noalias=yes, with this it will generate the same assembly for both (proof).
Alternatively your function could take a &mut [usize]. This removes a layer of indirection, allowing LLVM to see that the slice reference itself is never modified and so it can be sure the length is never modified as well.