https://issues.dlang.org/show_bug.cgi?id=20901
Simen Kjaeraas <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |[email protected] --- Comment #1 from Simen Kjaeraas <[email protected]> --- A shorter piece of code that demonstrates the issue: import std.stdio : writeln; struct S { int[] front = [0]; bool empty() { return front[0] >= 2; } void popFront() { front[0]++; } } void main() { static foreach (e; S()) { writeln(e); // Writes [2] 2 times } } What happens is somewhat equivalent to this: // Happens at compile-time: S tmp; auto value1 = tmp.front; tmp.popFront(); auto value2 = tmp.front; tmp.popFront(); // Happens at run-time: writeln(value1); writeln(value2); Since there is no .dup anywhere to be found, value1 and value2 refer to the same array, so popFront() modifies both. Since all calls to popFront() happen at compile-time, before any of the values are used, only the final values are available. In fact, a deep duplication would be required for the values to be correct, which could cause other issues where you expect changing a value in one step would carry over to the next. So, static foreach does not deal well with ranges that modify referenced data, and I'm not sure this is an issue that can be properly fixed. static foreach looks like 'please unroll this loop', but is... something else. --
