It's surprisingly difficult to write something where the compiler doesn't detect that it's working on a constant. I had to code up a loop that pushed values onto the vector before the compiler generated the general case. "black_box" is not, apparently, opaque to the optimizer.
Ideomatic form, inner loop: [1]
LBB4_3:
cmp byte ptr [rax + rcx], 0
jne .LBB4_4
inc rcx
cmp rdx, rcx
jne .LBB4_3
C-like form, inner loop: [2]
.LBB4_3:
cmp byte ptr [rax + rcx], 0
jne .LBB4_4
inc rcx
cmp rdx, rcx
jne .LBB4_3
Both ways, the compiler found the optimal solution.
In the C-like loop, it was able to hoist and then elide the subscript check.
In the ideomatic form, it's implicit in the iterator that you won't go off the end of the array.
The lambda function was expanded inline and optimized.
There's zero call overhead from using a lambda function there.
Very nice work by the Rust compiler people and LLVM.
Original: https://godbolt.org/z/rPfEWPGc1
It’s cool to see the same code be generated. You can use “vec!” To stop it specializing the function in the length