www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 18807] New: RefRange behaves very differently for Input

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

          Issue ID: 18807
           Summary: RefRange behaves very differently for Input Ranges and
                    Forward Ranges
           Product: D
           Version: D2
          Hardware: All
               URL: http://dlang.org/
                OS: All
            Status: NEW
          Severity: major
          Priority: P3
         Component: phobos
          Assignee: nobody puremagic.com
          Reporter: eyal weka.io

Example program:

    import std.range: refRange, iota;

    struct R1 {
        auto r = iota(3);
        alias r this;
    }
    void works() {
        R1 r1;
        foreach(x; refRange(&r1)) {}
        assert(r1.empty);
    }

    struct R2 {
        auto r = iota(3);
        alias r this;
         property auto save() { return this; }
    }
    void explodes() {
        R2 r2;
        import std.range;
        foreach(x; refRange(&r2)) {}
        assert(r2.empty);       // <-- BOOM
    }

works() is fine.
explodes() fails on the assertion.

The only difference is that R2 defines save().

What happens is that the foreach calls opSlice (if it exists), which calls
save. opSlice exists iff save exists.

Upgrading an existing input range to a forward range invisibly breaks any code
that used foreach on a refRange of that range.

--
Apr 29 2018