March 25, 2015
https://issues.dlang.org/show_bug.cgi?id=12811

Kenji Hara <k.hara.pg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |INVALID

--- Comment #1 from Kenji Hara <k.hara.pg@gmail.com> ---
(In reply to bearophile_hugs from comment #0)
> import std.algorithm: filter;
> struct Foo {
>     bool bar(in int) @nogc {
>         return true;
>     }
>     auto spam() @nogc {
>         immutable static data = [1, 2];
>         return data.filter!(i => bar(i));

'filter' will lazily evaluate the given array outside of the 'spam' function, so the lambda 'i => bar(i)' needs to capture 'this' variable to call member function 'bar'.

It will make a closure allocation.

> This gives a similar error:
> 
> import std.algorithm: filter;
> struct Foo {
>     bool bar(in int) @nogc {
>         return true;
>     }
>     auto spam() @nogc {
>         immutable static data = [1, 2];
>         scope immutable f = (int i) => bar(i);
>         return data.filter!f;

To access the delegate variable f later, 'filter' should capture the function frame of 'spam' (and it will indirectly capture the 'this' of 'spam' function). It will need a closure allocation.

--
March 27, 2015
https://issues.dlang.org/show_bug.cgi?id=12811

--- Comment #2 from bearophile_hugs@eml.cc ---
(In reply to Kenji Hara from comment #1)

> 'filter' will lazily evaluate the given array outside of the 'spam' function, so the lambda 'i => bar(i)' needs to capture 'this' variable to call member function 'bar'.
> 
> It will make a closure allocation.

Thank you for the answer. We'll have to add some escape analysis to turn some closure heap allocations into stack allocations.

--