Attributes lost in TypeInfo, please advise

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Thu Feb 12 04:59:39 PST 2015


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


More information about the Digitalmars-d mailing list