Thread overview
[Issue 5730] __traits(compiles) does not handle "variable has scoped destruction, cannot build closure" error correctly
Jul 07, 2015
Kenji Hara
Mar 16, 2021
RazvanN
Mar 28, 2022
Iain Buclaw
Dec 17, 2022
Iain Buclaw
July 07, 2015
https://issues.dlang.org/show_bug.cgi?id=5730

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Hardware|Other                       |All
                 OS|Linux                       |All

--- Comment #5 from Kenji Hara <k.hara.pg@gmail.com> ---
(In reply to Max Samukha from comment #2)
> No, no. The bug is not about the impossibility to build a closure. It is about __traits(compiles) not handling the compilation error properly. It should suppress the error and evaluate to false.

Today, a delegate literal in __traits(compiles) does not make the outer function closure, because the delegate is just a thing only in compile time.

I'd provide better example code:

struct S
{
    ~this() {}
}

void main()
{
    enum r = __traits(compiles, {
        auto madeClosure()
        {
            S s;
            auto dg = { auto s1 = s; };
            return dg;
        }
    });
    static assert(!r);  // line 1
}

The madeClosure function will be made a closure, because the dg that refers local variable s will escape from that. Then the "has scoped destruction..." error needs to be captured by the __traits(compile) and r should be false.

--
March 16, 2021
https://issues.dlang.org/show_bug.cgi?id=5730

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
                 CC|                            |razvan.nitu1305@gmail.com
         Resolution|---                         |FIXED

--- Comment #6 from RazvanN <razvan.nitu1305@gmail.com> ---
Today this code compiles succesfully and prints "destructor":

struct S
{
    ~this()
    {
        import std.stdio;
        writeln("destructor");
    }
}

void main()
{
    S s;
    enum error = __traits(compiles, { auto s1 = s; });
    //static assert(!error); // line 1
}

It seems that the compiler is able to allocate the closure and also track it with the gc.

Closing as fixed.

--
March 28, 2022
https://issues.dlang.org/show_bug.cgi?id=5730

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
                 CC|                            |ibuclaw@gdcproject.org
         Resolution|FIXED                       |---

--- Comment #7 from Iain Buclaw <ibuclaw@gdcproject.org> ---
Related test still fails though.

struct S10666
{
    int val;
    ~this() {}
}


void foo10666(S10666 s1)
{
    // Error: s1 has scoped destruction, cannot build closure.
    auto f1 = (){ return () => s1.val; }();

    enum r1 = __traits(compiles, {
        auto f1 = (){ return () => s1.val; }();
    });
    static assert(!r1); // Error: static assert:  `!r1` is false
}

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=5730

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P2                          |P3

--