dmd icon indicating copy to clipboard operation
dmd copied to clipboard

[DRuntime] TypeInfo bug when using associative array + shared library

Open MrcSnm opened this issue 7 months ago • 3 comments

On main binary:

//other.d
class Other
{
}

//main.d
void main()
{
  import other;
  int[TypeInfo] typeMap = [
  typeid(Other]: 10
];
  //use dynamicaly loaded getType
  
  assert(getType() in typeMap);
}

On other binary:

TypeInfo getType()
{
  import other;
  return typeid(Other);
}

They have the same fully qualified name, same hash, but it still errors. Happens in both dmd and ldc2.

That may be due to

    // lookup a key
    inout(Bucket)* findSlotLookup(size_t hash, scope const void* pkey, scope const TypeInfo keyti) inout
    {
        for (size_t i = hash & mask, j = 1;; ++j)
        {
            if (buckets[i].hash == hash && keyti.equals(pkey, buckets[i].entry))
                return &buckets[i];
            else if (buckets[i].empty)
                return null;
            i = (i + j) & mask;
        }
    }

This is the function for finding the data. And as you can see, the equals implementation of TypeInfo differs from opEquals:


    bool opEquals(const TypeInfo ti) @safe nothrow const
    {
        /* TypeInfo instances are singletons, but duplicates can exist
         * across DLL's. Therefore, comparing for a name match is
         * sufficient.
         */
        if (this is ti)
            return true;
        return ti && this.toString() == ti.toString();
    }
     bool equals(in void* p1, in void* p2) const { return p1 == p2; }

Since they are void, no opEquals is actually called. I'm confused on what is the expected behavior. Of course I can simply use a string from typeinfo, but that wasn't the intended way to use at first.

MrcSnm avatar May 20 '25 14:05 MrcSnm

keyti here should be the TypeInfo of a TypeInfo, which is a TypeInfo_Class. And that .equals() casts the void* params to Object: https://github.com/dlang/dmd/blob/baee0d8080011ed357a0351ca1aebbb3c1abb41d/druntime/src/object.d#L1601-L1607

And that should then invoke TypeInfo.opEquals() that you linked above.

kinke avatar May 22 '25 11:05 kinke

Humm yeah that makes sense, but now I wonder why it is still not working then

MrcSnm avatar May 22 '25 12:05 MrcSnm

I suggest using LDC's -link-defaultlib-debug and stepping through it with a debugger.

kinke avatar May 22 '25 12:05 kinke