A slightly more complex example, illustrating that it wouldn't be enough to check that the delegate body itself doesn't mutate the captured variable:

```
int delegate() increment;

auto foo(int x)
{
   increment = () => ++x;
   return () => x;
}

void main()
{
    auto dg = foo(42);
    auto dg_copy = dg;

    assert(dg() == 42);

    assert(increment() == 43);
        assert(dg() == 43);
    assert(dg_copy() == 43);
}
```

In the end, I think it really boils down to that the optimized state would be per-delegate (and tied to its lifetime) instead of shared (as we see above, even across lambdas) and GC-managed (and so can happily escape, see one of my earlier posts). So all use of it as lvalue (taking the address, assigning, passing by ref etc.) isn't allowed in the delegate body itself, and to make sure no other lambda mutates it, it needs to be const.

But there are also GC-using delegates which could be optimized this way.

This should read: lambdas in a non-@nogc parent function are optimization candidates too, and the lambda bodies can use the GC as well.

Reply via email to