Skip to content

Commit 60e0d7a

Browse files
dkorpelclaude
andcommitted
Fix #23731 - undefined __xopEquals/__xtoHash for instantiated struct
786dc71 stopped emitting the special TypeInfo members alongside the TypeInfo of a template-instantiated struct whose own codegen was elided, assuming they are always emitted with the StructDeclaration elsewhere. That does not hold when `ti.minst` is null (a speculative instance whose TypeInfo was requested anyway) or a non-root module that is not part of the compilation: nothing emits `TemplateInstance.toObjFile()`, so the TypeInfo emitted here is left referencing symbols no object file defines. Restore emitting them next to the TypeInfo, as before 2.113. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 2c7448c commit 60e0d7a

3 files changed

Lines changed: 39 additions & 0 deletions

File tree

compiler/src/dmd/glue/todt.d

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,25 @@ private extern (C++) class TypeInfoDtVisitor : Visitor
14911491
semanticTypeInfoMembers(sd);
14921492
}
14931493

1494+
if (TemplateInstance ti = sd.isInstantiated())
1495+
{
1496+
if (!ti.needsCodegen())
1497+
{
1498+
if (sd.xeq && sd.xeq != StructDeclaration.xerreq)
1499+
toObjFile(sd.xeq, global.params.multiobj);
1500+
if (sd.xcmp && sd.xcmp != StructDeclaration.xerrcmp)
1501+
toObjFile(sd.xcmp, global.params.multiobj);
1502+
if (FuncDeclaration ftostr = search_toString(sd))
1503+
toObjFile(ftostr, global.params.multiobj);
1504+
if (sd.xhash)
1505+
toObjFile(sd.xhash, global.params.multiobj);
1506+
if (sd.postblit)
1507+
toObjFile(sd.postblit, global.params.multiobj);
1508+
if (sd.dtor)
1509+
toObjFile(sd.dtor, global.params.multiobj);
1510+
}
1511+
}
1512+
14941513
/* Put out:
14951514
* char[] mangledName;
14961515
* void[] init;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module imports.test23731a;
2+
3+
struct Wrapper(T)
4+
{
5+
T[] values;
6+
}
7+
8+
enum wrapperIntSize = Wrapper!int.sizeof;

compiler/test/runnable/test23731.d

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// https://github.com/dlang/dmd/issues/23731
2+
3+
import imports.test23731a;
4+
5+
void main()
6+
{
7+
auto ti = typeid(Wrapper!int);
8+
auto a = Wrapper!int([1, 2]);
9+
auto b = Wrapper!int([1, 2]);
10+
assert(ti.equals(&a, &b));
11+
assert(ti.getHash(&a) == ti.getHash(&b));
12+
}

0 commit comments

Comments
 (0)