On 2/11/15 11:08 PM, Jakob Ovrum wrote:
Consider the following:

---
struct S
{
     ~this() @safe {}
}

void foo() @safe
{
     S s;
     // OK
}

void bar() @safe
{
     S s;
     destroy(s);
     // test.d(15): Error: safe function 'test.bar' cannot call system
function 'object.destroy!(S).destroy'
}
---

`destroy` is used in algorithms using low-level operations like
`emplace[Ref]`, and while `destroy` itself is a template and thus enjoys
attribute inference, it calls the non-generic typeid(T).destroy
function, which is unconditionally @system. This unsafety then
propagates all the way up to high-level code that is otherwise inferred
to be safe.

The `postblit` TypeInfo method, used from `emplace[Ref]`, has the same
problem.

Is it possible to call the destructor or postblit constructor directly,
and will they correctly destruct/copy recursively like
TypeInfo.destroy/postblit do? If so, we should change `destroy` and
`emplaceImpl` to use direct calls ASAP.

The reason typeid.destroy is used is because it does what you think calling the destructor directly should do. As Adam pointed out, __dtor does not do it right.

Note, there is a hidden function generated by the compiler, that TypeInfo.destroy maps to. There is no way to call it directly.

There is a bug report that shows why we do it that way (recall that destroy was once named clear): https://issues.dlang.org/show_bug.cgi?id=5667

I think given the necessity of the above (which was not discussed or noticed in that bug report), we should add a way to call the true destructor properly in the compiler.

-Steve

Reply via email to