On Sunday, 27 May 2018 at 09:55:56 UTC, Mike Franklin wrote:
TypeInfo has become my nemesis. I've been trying to replace runtime hooks that depend on TypeInfo with templates that can get their information at compile-time, but I'm running into all sorts of problems. e.g. Did you know array.length can be set in @safe nothrow pure code, but it lowers to runtime functions that are neither @safe, nothrow, nor pure?

Ouch.

Anyway, I'm getting better at modifying the compiler/runtime interface. If we can come up with a solution to this mess, and I can understand it, I might be able to implement it.

I've been meaning to learn more about how the compiler/runtime interface works myself but still haven't got around it. I'm probably going to learn a lot by looking at your PRs.

I've been thinking this through a bit, and here's what I've got so far:

At first I obviously wanted an all-round "just works" low-level interface for destroying objects. But after looking at how people are using __dtor/__xdtor in real code, and looking at the PRs for destroy(), it's obvious that there's a lot of disagreement about what that means. Let's leave that topic for now.

If we just focus on fixing classes, we can add, say, __vdtor (I really don't care much about the name, BTW). This needs to be a normal virtual function in the vtable (preferably in a way that's compatible with C++ ABIs) that runs the user-defined destructor code, then recursively calls destructors for members and base classes.

The generation of __vdtor also needs a special case to make attributes work. Something like "an empty destructor has attributes inferred like templated functions are, restricted by any of its bases". For example, this needs to work:

extern(C++)
{

class Base
{
    // Virtual
    ~this() @nogc
    {
    }
}

class Derived
{
    // Not marked pure but is still @nogc
// (NB: explicitly marking @nogc isn't needed in current language)
    override ~this() @nogc
    {
    }
}

class Derived2 : Derived
{
    override ~this() @nogc pure
    {
// Marked pure, but still recurses to empty destructors in Derived and Base
    }
}

}

Right now __vdtor would need to be implemented with a thunk that wraps around __xdtor (like I implemented here: https://theartofmachinery.com/2018/05/27/cpp_classes_in_betterc.html). But if __vdtor is implemented, the D runtime code can be simplified to use __vdtor for classes, then hopefully we can deprecate and remove __dtor and __xdtor for classes, and then __vdtor can become the native destructor implementation.

Reply via email to