I'm unable to implement an @nogc hash table that has immutable keys that have dtors and contain members with dtors. Here is the reduced version of such a structure:
struct HashTable
{
immutable(Key)* keys;
~this()
{
destroy( keys[0] );
}
}
struct Key
{
KeyData data;
~this() const {}
}
struct KeyData
{
~this() const {}
}
The compiler will complain:
Error: mutable method main.Key.~this is not callable using a immutable object
Error: template instance object._destructRecurse!(immutable(Key)) error instantiating
This seems to come from calling an aggregated non-const destructor and I don't know of a feasible workaround. The ones I know of are:
1) remove immutability from keys and const from dtors
2) merge KeyData's dtor into that of Key (but Key is a generic templated wrapper struct)
Comment #1 by dlang-bugzilla — 2017-07-02T15:33:31Z
I believe the operation destroy(x) where x is an immutable value type was never supported, as part of destroy's operation is to clobber the value of x with its .init value - see object.d, the `void destroy(T)(ref T obj) if (is(T == struct))` overload.
Changing the destroy() call with an explicit invocation of the inclusive destructor (`keys[0].__xdtor();`) does seem to illustrate the problem better, I think - the inclusive destructor should have its constness inferred from the destructors it calls:
$ cat test.d
struct HashTable
{
immutable(Key)* keys;
~this()
{
keys[0].__xdtor();
}
}
struct Key
{
KeyData data;
~this() const {}
}
struct KeyData
{
~this() const {}
}
$ dmd -o- test.d
test.d(7): Error: mutable method test.Key.~this is not callable using a immutable object
Comment #2 by robert.schadek — 2024-12-13T18:46:45Z