Jump to page: 1 2
Thread overview
[Issue 21912] Invalid stack closure when calling delegate inside lambda
May 12
Dennis
May 14
Dennis
May 15
Dennis
[Issue 21912] delegate assigned to return scope variable needs closure
Jul 15
Dennis
Jul 15
Dlang Bot
4 days ago
Dlang Bot
May 10
https://issues.dlang.org/show_bug.cgi?id=21912

Sebastiaan Koppe <mail@skoppe.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mail@skoppe.eu

--- Comment #1 from Sebastiaan Koppe <mail@skoppe.eu> ---
The above is a reproduction of a problem I have seen occur several times now.

It always involves a delegate that refers to a parameter. D is supposed to move the parameter to the heap, creating a closure. But as you can see above, in more complex cases it produces garbage.

--
May 10
https://issues.dlang.org/show_bug.cgi?id=21912

moonlightsentinel@disroot.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |moonlightsentinel@disroot.o
                   |                            |rg

--- Comment #2 from moonlightsentinel@disroot.org ---
Slightly reduced:

@safe:

auto foo(DG)(DG dg, int p) {
    return () => dg(p);
}

auto bla(int i) {
    return foo((int p)=>i*p, 66);
}

void main() {
    assert(bla(5)() == 330);
}

=====================================

Only requires -dip1000 which probably hints at invalid scope inference.

--
May 10
https://issues.dlang.org/show_bug.cgi?id=21912

--- Comment #3 from moonlightsentinel@disroot.org ---
Even smaller:

=================================
DG foo(DG)(DG dg) {
    return dg;
}

auto bla(int i) {
    return foo(() => i);
}

void main() {
    assert(bla(5)() == 5);
}
=================================

--
May 12
https://issues.dlang.org/show_bug.cgi?id=21912

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |dkorpel@live.nl
         Resolution|---                         |DUPLICATE

--- Comment #4 from Dennis <dkorpel@live.nl> ---
This has to do with pure bypassing scope checks:

```
int delegate() pure foo(int delegate() pure dg) pure {
    return dg;
}

int delegate() bla(int i) pure {
    return foo(() => i);
}

void main() {
    assert(bla(5)() == 5);
}
```

*** This issue has been marked as a duplicate of issue 20150 ***

--
May 14
https://issues.dlang.org/show_bug.cgi?id=21912

--- Comment #5 from Sebastiaan Koppe <mail@skoppe.eu> ---
Could you explain what that has to do with the compiler deciding not to allocate the closure?

--
May 14
https://issues.dlang.org/show_bug.cgi?id=21912

--- Comment #6 from Dennis <dkorpel@live.nl> ---
(In reply to Sebastiaan Koppe from comment #5)
> Could you explain what that has to do with the compiler deciding not to allocate the closure?

The closure is not allocated because parameter `dg` of `foo` is inferred
`scope`.
`dg` is inferred `scope` because `foo` is inferred (or annotated) `pure`.
The faulty logic that `pure implies scope` is described in the linked issue.

See also the forum post I made about it: https://forum.dlang.org/post/jnkdcngzytgtobihzggj@forum.dlang.org

--
May 15
https://issues.dlang.org/show_bug.cgi?id=21912

--- Comment #7 from Sebastiaan Koppe <mail@skoppe.eu> ---
I read the post, and it sure looks plausible, I just don't understand it.

If this has to do with "pure bypassing scope checks", then making one of the above examples un-pure would solve it. Although it does work with your reduced case, not with the ones where foo has a DG template parameter.

That still crashes:

```
void unpure() @trusted { static int g; g = 5; }

DG foo(DG)(DG dg) {
    unpure();
    return dg;
}

auto bla(int i) {
    return foo((){ unpure(); return i;});
}

void main() {
    pragma(msg, typeof(bla)); // @safe int delegate() @safe(int i)
    assert(bla(5)() == 5); // Assertion failure
}
```

What does work though, is to assign the delegate to a variable first. This compiles (also with the other DG template examples):

```
int delegate() pure foo(int delegate() pure dg) pure {
    return dg;
}

int delegate() bla(int i) pure {
    auto dg = () => i;
    return foo(dg);
}

void main() {
    assert(bla(5)() == 5); // Pass!
}
```

--
May 15
https://issues.dlang.org/show_bug.cgi?id=21912

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|DUPLICATE                   |---

--- Comment #8 from Dennis <dkorpel@live.nl> ---
(In reply to Sebastiaan Koppe from comment #7)
> If this has to do with "pure bypassing scope checks", then making one of the above examples un-pure would solve it. Although it does work with your reduced case, not with the ones where foo has a DG template parameter.

You're right, it turns out there is another issue at play. Reduced to explicit attributes:

```
int delegate() foo(return int delegate() dg) {
    return dg;
}

int delegate() bla(int i) {
    return foo(() => i);
}

void main() {
    assert(bla(5)() == 5);
}
```

Since () => i is assigned to a `return` parameter, the expression `foo(() =>
i)` should be `scope` and cannot be returned from `bla` without allocating a
closure with i on the heap.

I quickly looked at the existing dip1000 issues but couldn't find something similar enough, so let's re-open it.

--
May 16
https://issues.dlang.org/show_bug.cgi?id=21912

Ketmar Dark <ketmar@ketmar.no-ip.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ketmar@ketmar.no-ip.org

--
July 15
https://issues.dlang.org/show_bug.cgi?id=21912

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Invalid stack closure when  |delegate assigned to return
                   |calling delegate inside     |scope variable needs
                   |lambda                      |closure

--
« First   ‹ Prev
1 2