On 2013-04-02 15:03, Kenji Hara wrote:

I think this is not a hole of inout design. In this case, the lambda
inside foo should capture 'inout' context pointer.

void foo (inout int[] arr)
{
     auto dg = {
         foreach (i, e ; arr) {}
     };
     pragma(msg, typeof(dg));  // should print "void delegate() inout"
     dg();
}

I'm assuming the issue is that the compiler is trying to generate a
struct to hold the stack data for foo, and struct members cannot be
inout.

It is true, but in this case, the context which is implicitly captured
by closure is not directly accessible from programmers. So qualifying it
'inout' is safe.

It is a difficult problem to solve, because inout has two meanings
depending on whether it is a parameter/return or a local variable.  At
some point, we need to address this, because inout has so much
potential, but suffers from some large deficiencies.

And, inout closure cannot escape from enclosing inout function.

auto foo(inout int[] arr)
{
     auto dg = (inout int[] a)
     {
         return arr;   // returns captured inout 'arr'
     };
     return dg;  // escape! (should be rejected statically)
}

If compiler does not reject escape...

void main()
{
     const int[] a = [3, 4, 5];
     auto dg = foo(a);
     // typeof(dg) == inout(int[]) delegate(inout(int[]))
     int[] b = dg([]);
     assert(b.ptr == a.ptr);  // type-system breaking!
}

Kenji Hara

Then I should probably report this as an issue.

--
/Jacob Carlborg

Reply via email to