digitalmars.D.bugs - [Issue 16374] New: Foreach lowering tries opSlice before range
- via Digitalmars-d-bugs (49/49) Aug 10 2016 https://issues.dlang.org/show_bug.cgi?id=16374
https://issues.dlang.org/show_bug.cgi?id=16374 Issue ID: 16374 Summary: Foreach lowering tries opSlice before range primitives Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: lodovico giaretart.net CC: lodovico giaretart.net When lowering a foreach, the compiler gives priority to opSlice over front/popFront/empty, which is counter-intuitive (and also undocumented). The following code, taken from [1] shows the issue: the overridden front in RangeWrapper is ignored when the wrapped range also defines opSlice, which is true for RangeT (the range returned by Array.opSlice). This causes the foreach output to be different from the expected old-style for loop equivalent. Example code: ===================================================== import std.stdio, std.container.array; struct RangeWrapper(Range) { Range range; alias range this; auto front() { return range.front + 1; } } auto rangeWrapper(Range)(auto ref Range range) { return RangeWrapper!Range(range); } void main() { Array!int array; array.insertBack(3); foreach (i; rangeWrapper(array[])) writeln(i); // prints 3, which is wrong // isn't the above foreach equivalent to the following loop ? for (auto r = rangeWrapper(array[]); !r.empty; r.popFront()) writeln(r.front); // correctly prints 4 } ===================================================== [1] http://forum.dlang.org/thread/fzwofczyvkxgmtvncmxb forum.dlang.org --
Aug 10 2016