I'm trying to write reference counted dynamic array and encountered a trouble with compile time reflection at recursive template instantiation.

for dynamic arrays (and AA too) it is normal to use recursive declarations:

struct S {
    S[] arr;
}

struct S {
    Array!S arr;
}

Look at this code: (DPaste - https://dpaste.dzfl.pl/2010191369fe)
import std.string : format;

struct Bar(E) {
    void fun() {
pragma(msg, format("fun: Foo.__xdtor - %s", __traits(hasMember, E, "__xdtor"))); pragma(msg, format("fun: Bar.__xdtor - %s", __traits(hasMember, Bar, "__xdtor"))); pragma(msg, format("fun: Foo.__dtor - %s", __traits(hasMember, E, "__dtor"))); pragma(msg, format("fun: Bar.__dtor - %s", __traits(hasMember, Bar, "__dtor")));
    }
    ~this() {
pragma(msg, format("~this: Foo.__xdtor - %s", __traits(hasMember, E, "__xdtor"))); pragma(msg, format("~this: Bar.__xdtor - %s", __traits(hasMember, Bar, "__xdtor"))); pragma(msg, format("~this: Foo.__dtor - %s", __traits(hasMember, E, "__dtor"))); pragma(msg, format("~this: Bar.__dtor - %s", __traits(hasMember, Bar, "__dtor")));
    }
}

struct Foo {
    Bar!Foo foo;
    ~this() {}
}

void main() {}

Output:
~this: Foo.__dtor - true        <--- Foo has __dtor, OK,
~this: Bar.__dtor - true
~this: Foo.__xdtor - false      <--- but hasn't __xdtor. WAT???
~this: Bar.__xdtor - true
fun: Foo.__dtor - true
fun: Bar.__dtor - true
fun: Foo.__xdtor - true
fun: Bar.__xdtor - true

Global object.destroy(ref T) function detects destructor presence by __traits(hasMember, T, "__xdtor") (https://github.com/dlang/druntime/blob/v2.073.2/src/object.d#L2440) and does nothing in such cases.

Workaround:
Avoid reflection in the destructor. Do reflection in normal function and then call it from destructor.

But it looks weird and should be fixed.

Also see related topic: https://forum.dlang.org/thread/[email protected]

Reply via email to