4 ms·
You're right but in this case it doesn't change anything (you can replace break; with return; and you won't have a warning either). Actually, even if you add c
by simias 12y ago
You're right but in this case it doesn't change anything (you can replace break; with return; and you won't have a warning either).
Actually, even if you add code after the for loop and the list is not empty Rust does not warn:
fn main() {
let l = [1i, 2, 3];
for i in l.iter() {
println!("{}", i);
return;
}
println!("unreached");
}
Builds without warning and prints a single "1".
Judging by the output with "--emit ir" when building with -O the rust compiler doesn't seem clever enough yet to realize that the whole vector and loop could just be factorized in a single "println!("{}", 1); return;" which probably explains why it can't detect that the return is always reached (i.e. the list is never empty). It even generates instructions to create the unused array elements:
%1 = getelementptr inbounds [3 x i64]* %l, i64 0, i64 0
store i64 1, i64* %1, align 8
%2 = getelementptr inbounds [3 x i64]* %l, i64 0, i64 1
store i64 2, i64* %2, align 8
%3 = getelementptr inbounds [3 x i64]* %l, i64 0, i64 2
store i64 3, i64* %3, align 8
- eddyb 12y agoThe Rust compiler cannot assume the loop will never iterate, the analysis phases that could determine that are ran before optimizations. And optimizations are performed by LLVM, with no feedback to the compiler. I actually analyzed your example, and what happens there is that `i` is a reference to array elements and we don't pass enough metadata to LLVM to inform it of pointers with a fixed number of usable bytes, so it believes the formatting runtime is capable of accessing more of the array.