On 10/12/17 14:00, Shachar Shemesh wrote:
On 10/12/17 13:44, Jonathan M Davis wrote:
it sounds like the delegate that's
being generated isn't @nogc, so it can't be called within the function,
which would be a completely different issue from allocating a closure.

Here's the thing, though. There is no reason for the delegate to be called at all!

Since func1's msg is also lazy, I expected the lowering to look like this:

void func1(/*scope*/ string delegate() msg) @nogc {
}

void func2(/*scope*/ string delegate() msg) @nogc {
   func1(msg);
}

Even with scope commented out, the above compiles just fine. The fact that msg is not @nogc doesn't matter at all, simply because no one is evaluating the delegate.

I think I got it. I think the lowering is this:

void func1(/*scope*/ string delegate() msg) @nogc {
}

void func2(/*scope*/ string delegate() msg) @nogc {
  func1((){ return msg(); });
}

With "scope" commented out, this generates the following error:
test.d(15): Error: function test.func2 is @nogc yet allocates closures with the GC test.d(16): test.func2.__lambda2 closes over variable msg at test.d(15)

So there are two problems here. The first is that a "lazy" generated delegate does not get forwarded to a function, and instead gets wrapped by a completely useless temporary delegate. The second is that scope on lazy is not honored.

I'll file a bug report.

Shachar

Reply via email to