www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 17873] New: Foreach over variadics implicitly evaluates lazy

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

          Issue ID: 17873
           Summary: Foreach over variadics implicitly evaluates lazy
                    arguments
           Product: D
           Version: D2
          Hardware: x86
                OS: Windows
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: simen.kjaras gmail.com

When foreach-ing over a variadic argument list, lazy arguments are implicitly
evaluated, as demonstrated here:

void foo(lazy int n) {}

void bar(T...)(lazy T args) {
    foreach (e; args) {
        // Look ma, no touchy!
    }
}

unittest {
    int n = 3;
    foo(n++);
    assert(n == 3); // passes
    bar(n++);
    assert(n == 3); // fails
}

Note that static foreach over the same argument list does not evaluate lazy
args, and require that arguments be explicitly referenced for evaluation to
take place:

auto bar2(T...)(lazy T args) {
    static foreach (i, e; args) {
    }
}

auto baz2(T...)(lazy T args) {
    static foreach (e; args) {
    }
}

auto bar3(T...)(lazy T args) {
    static foreach (i, e; args) {
        e;
    }
}

auto baz3(T...)(lazy T args) {
    static foreach (e; args) {
        e;
    }
}

unittest {
    int n = 3;
    bar2(n++);
    assert(n == 3); // passes
    baz2(n++);
    assert(n == 3); // passes
    bar3(n++);
    assert(n == 4); // passes
    baz3(n++);
    assert(n == 5); // passes
}

--
Oct 02 2017