1 // PERMUTE_ARGS:
2 
3 struct Field
4 {
~thisField5     ~this() @safe @nogc pure nothrow {}
6 }
7 
8 struct Counter
9 {
10     static size_t cnt;
~this()11     ~this() @safe @nogc nothrow { ++cnt; }
12 }
13 
14 struct Foo
15 {
~thisFoo16     ~this() @safe @nogc pure nothrow {}
17     Field field;
18 }
19 
20 class Bar
21 {
~this()22     ~this() @safe @nogc pure nothrow {}
23     Field field;
24 }
25 
test1()26 void test1() @nogc pure nothrow
27 {
28     Foo foo;
29     foo.__xdtor();
30     scope bar = new Bar();
31     bar.__xdtor();
32 }
33 
34 static assert(__traits(hasMember, Foo, "__xdtor"));
35 static assert(__traits(hasMember, Bar, "__xdtor"));
36 
37 //
38 
39 struct FieldDtor
40 {
41     Counter counter;
42 }
43 
44 struct AggrDtor
45 {
46     static size_t cnt;
~this()47     ~this() @safe @nogc nothrow { ++cnt; }
48 }
49 
50 struct MixedDtor
51 {
52     static size_t cnt;
53     Counter counter;
~thisMixedDtor54     ~this() @safe @nogc nothrow { ++cnt; }
55 }
56 
57 struct SNoDtor {}
58 class CNoDtor {}
59 
60 static assert(!__traits(hasMember, SNoDtor, "__xdtor"));
61 static assert(!__traits(hasMember, CNoDtor, "__xdtor"));
62 
test2()63 void test2() @safe @nogc nothrow
64 {
65     FieldDtor a;
66     assert(Counter.cnt == 0);
67     a.__xdtor();
68     assert(Counter.cnt == 1);
69     AggrDtor b;
70     assert(AggrDtor.cnt == 0);
71     b.__xdtor();
72     assert(AggrDtor.cnt == 1);
73     Counter.cnt = 0;
74     MixedDtor c;
75     assert(MixedDtor.cnt == 0);
76     assert(Counter.cnt == 0);
77     c.__xdtor();
78     assert(MixedDtor.cnt == 1);
79     assert(Counter.cnt == 1);
80 }
81 
main()82 void main()
83 {
84     test1();
85     test2();
86 }
87