Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> for i in 0..(xs.len()) { let x = xs[i]; // do something with x } > should really be this:

> for x in &xs { // do something with x }

I am curious why the compiler can't rewrite the former to the latter?



Because in the former case, the optimizer has to prove that the length of the array cannot change during the body of the loop, while in the latter case, that's guaranteed by the language semantics.


Also because the iterator could do something completely different from an iteration by sequential index no?


Doesn't `let x = xs[i]` immutably borrow from xs? So for the duration of x's lifetime (which is the entire for-body block), xs cannot be changed and therefore its length must remain the same.

Though this might be information that rustc knows about but not LLVM.


In the case of "let x = &xs[i]" it would immutably borrow. But we'd need more MIR optimizations to make use of that fact.


A Sufficiently Smart Compiler would be able to.

The second just increments a pointer which starts at the first elem of the array; the first increments a counter and then uses it as an offset into the array, which is bounds checked (the second never generates bounds checks). Proving that that counter never exceeds the end of the array, so the bounds check can be dropped, is not trivial.


At least in simple cases, it generates almost identical code for both: https://godbolt.org/g/twuLd1

(I may have gotten something wrong, this is my first Rust program! Yay!)




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: