digitalmars.D - Something wrong with reflection inside struct destructor
- Jack Applegame (58/58) Mar 14 2017 I'm trying to write reference counted dynamic array and
- Jack Applegame (3/6) Mar 14 2017 This doesn't work - https://dpaste.dzfl.pl/5a1d93f7a277
- Jack Applegame (33/33) Mar 14 2017 This is completely unacceptable:
- John Colvin (2/9) Mar 14 2017 bug report?
- Jack Applegame (2/3) Mar 14 2017 https://issues.dlang.org/show_bug.cgi?id=17257
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/okbzqkjijuwvmvstjnzk forum.dlang.org
Mar 14 2017
On Tuesday, 14 March 2017 at 12:44:16 UTC, Jack Applegame wrote:Workaround: Avoid reflection in the destructor. Do reflection in normal function and then call it from destructor.This doesn't work - https://dpaste.dzfl.pl/5a1d93f7a277 Call from destructor changes compiler behavior. This is terrible.
Mar 14 2017
This is completely unacceptable: DPaste(https://dpaste.dzfl.pl/f54f578c4ec9) import std.stdio; import std.string; import std.experimental.allocator; import std.experimental.allocator.mallocator : Mallocator; struct Bar(E) { E* ptr = null; void allocate(int m) { ptr = Mallocator.instance.make!Foo(m); } ~this() { if(ptr !is null) Mallocator.instance.dispose(ptr); } } struct A { int m; ~this() { writefln("A.~this(%s)", m); } } struct Foo { A a; Bar!Foo bar; this(int m) { a = A(m); } } void main() { auto foo = Foo(1); foo.bar.allocate(10); } Output: A.~this(1) Expected output: A.~this(10) A.~this(1) Can someone to fix this ASAP for $100?
Mar 14 2017
On Tuesday, 14 March 2017 at 13:38:52 UTC, Jack Applegame wrote:On Tuesday, 14 March 2017 at 12:44:16 UTC, Jack Applegame wrote:bug report?Workaround: Avoid reflection in the destructor. Do reflection in normal function and then call it from destructor.This doesn't work - https://dpaste.dzfl.pl/5a1d93f7a277 Call from destructor changes compiler behavior. This is terrible.
Mar 14 2017
On Tuesday, 14 March 2017 at 14:33:49 UTC, John Colvin wrote:bug report?https://issues.dlang.org/show_bug.cgi?id=17257
Mar 14 2017