Thread overview
[Issue 23923] `this` not captured by lazy expression
May 18, 2023
Vladimir Panteleev
May 18, 2023
Vladimir Panteleev
Jul 15
RazvanN
May 18, 2023
https://issues.dlang.org/show_bug.cgi?id=23923

--- Comment #1 from Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> ---
(In reply to Vladimir Panteleev from comment #0)
> so the implicit reference to `this` (or other locals) would not be allowed.

so escaping the lazy expression in lazyFun would not be allowed.*

--
May 18, 2023
https://issues.dlang.org/show_bug.cgi?id=23923

--- Comment #2 from Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> ---
(In reply to Vladimir Panteleev from comment #0)
>         lazyFun({
>             virtualFunc();
>         }());

This could simply be:

        lazyFun(virtualFunc());

--
April 23
https://issues.dlang.org/show_bug.cgi?id=23923

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #3 from Walter Bright <bugzilla@digitalmars.com> ---
Lazy functions are implemented as delegates, so to investigate this, redo the lazy function as an explicit delegate. If the behavior is correct, then the fix is to figure out where lazy function checking diverges from delegate checking.

--
April 23
https://issues.dlang.org/show_bug.cgi?id=23923

--- Comment #4 from Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> ---
The issue does not occur when lazy is replaced with an explicit delegate.

//////////////// test.d ////////////////
@safe:

void delegate() later;

void lazyFun(void delegate() @safe expr)
{
    later = { expr(); };
}

class C
{
    void virtualFunc() {}

    final void run()
    {
        lazyFun({
            virtualFunc();
        });
    }
}

void main()
{
    auto c = new C;
    c.run();
    later();
}
////////////////////////////////////////

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

RazvanN <razvan.nitu1305@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |razvan.nitu1305@gmail.com

--- Comment #5 from RazvanN <razvan.nitu1305@gmail.com> ---
Hmmm, there's seems to be a problem with the creation of the second delegate in the original code (the first delegate is created when virtualFunc() is passed to the lazy parameter). If the delegate is extracted directly, the context pointer is preserved correctly:

//@safe:

void delegate() later;

void lazyFun(lazy void expr)
{
    later = &expr;
    //later = { expr; };
}

class C
{
    void virtualFunc() {}

    final void run()
    {
        lazyFun(virtualFunc());
    }
}

void main()
{
    auto c = new C;
    c.run();
    later();
}

However, the code is not safe anymore.

--