www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 14619] New: foreach implicitly slices ranges

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 puremagic.com
          Reporter: ag0aep6g 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.

--
May 24 2015