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
