I ran into a strange and hard-to-describe problem with nested functions closing over the argument to their enclosing function.

When a nested function (A) returns the value of another nested function (B) that returns a parameter of the enclosing function (C), and when (A) is returned from (C), then calling (A) returns an incorrect value if (A) has a parameter of class type (it works when (A) has no class parameters).

The code below demonstrates this (using DMD 2.058, no optimizations). Is this a bug?


auto foo(T)(int val)
{
    int nested()
    {
        return val;
    }

    int escaping(T ignored)
    {
        return nested();
    }

    return &escaping;

//    return &nested; // this works
}

struct Bar {}

class Baz {}

void main()
{
    auto func1 = foo!int(55);
    auto val1 = func1(12);
    assert(val1 == 55); // works fine with integral type

    auto func2 = foo!Bar(55);
    Bar bar;
    auto val2 = func2(bar);
    assert(val2 == 55); // works fine with struct

    auto func3 = foo!Baz(55);
    auto baz = new Baz();
    auto val3 = func3(baz);
    assert(val3 == 55); // fails; val3 is different value on each run
}

Reply via email to