[Issue 14619] New: foreach implicitly slices ranges

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Sun May 24 15:44:48 PDT 2015


https://issues.dlang.org/show_bug.cgi?id=14619

          Issue ID: 14619
           Summary: foreach implicitly slices ranges
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Keywords: wrong-code
          Severity: normal
          Priority: P1
         Component: DMD
          Assignee: nobody at puremagic.com
          Reporter: ag0aep6g at gmail.com

----
import std.stdio;

class C
{
    uint i;

    @property bool empty() {return i == 2;}
    @property uint front() {return i;}
    void popFront() {++i;}

    @property C save() {auto c = new C; c.i = this.i; return c;}
    C opSlice() {return save;}
}

void main()
{
    auto c = new C;
    foreach(e; c)
    {
        assert(e == c.front); /* fails */
    }
}
----

The assert passes without opSlice.

This makes std.range.refRange unusable with foreach:
----
import std.range: empty, refRange;
void main()
{
    auto a = [1, 2, 3];
    foreach(e; refRange(&a)) {}
    assert(a.empty); /* fails */
}
----

This has apparently been introduced to allow foreach over containers; see issue
5605. I think slicing should only be done when the aggregate isn't foreachable
itself already.

--


More information about the Digitalmars-d-bugs mailing list