minimized reproduction test case:
--- protocol.d
enum hasCallableFoobar(T) = __traits(compiles,
{
T.init.foobar();
});
size_t barfoo(T)(T )
if (is(T == S[], S) && hasCallableFoobar!S)
{
return 0;
}
size_t barfoo(T)(T val)
{
static if (hasCallableFoobar!T)
return val.foobar;
}
template ResolveThis(T)
{
static if (is(T : SelfRef!U, U))
alias ResolveThis = T;
else
alias ResolveThis = SelfRef!T[];
}
struct SelfRef(T)
{
ResolveThis!T payload;
size_t foobar()
{
static if (__traits(compiles, barfoo(payload)))
barfoo(payload);
return 0;
}
}
alias SelfRefArray = SelfRef!bool;
--- foo.d
import protocol;
unittest
{
SelfRef!(SelfRefArray) x;
}
---
to test:
#!/bin/bash
dmd -lib -ofprotocol.a protocol.d
dmd -main -c -oflib.o -unittest -I. foo.d
dmd -oftestlib lib.o protocol.a
observe that there is no compiler error for potential issues, but also we are failing with a linker error:
ld: error: undefined symbol: _D8protocol__T7SelfRefTbZQl6foobarMFNaNbNiNfZm
>>> referenced by __main.d
>>> lib.o:(_D8protocol__T6barfooTSQv__T7SelfRefTbZQlZQBcFNaNbNiNfQBgZm)
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
Note: in my actual code this is much much more complex, basically calling
Variant!MyVariant j;
j.match!(v => v);
with MyVariant being defined as Variant!JsonAlgebraic in another compilation unit.
Comment #1 by d.bugs — 2022-06-13T14:35:03Z
note:
linker looks for
_D8protocol__T7SelfRefTbZQl6foobarMFNaNbNiNfZm
demangled: `pure nothrow @nogc @safe ulong protocol.SelfRef!(bool).SelfRef.foobar()`
the protocol.a file contains the following foobar symbol:
_D8protocol__T7SelfRefTbZQl6foobarMFNbZm
demangled: `nothrow ulong protocol.SelfRef!(bool).SelfRef.foobar()`
so it looks like the foo.d module doesn't resolve the attributes consistently with the other compilation unit.
Comment #2 by kinke — 2022-06-13T16:32:21Z
(In reply to Jan Jurzitza from comment #1)
> so it looks like the foo.d module doesn't resolve the attributes
> consistently with the other compilation unit.
Yep, probably the same issue as https://issues.dlang.org/show_bug.cgi?id=23127.
Comment #3 by d.bugs — 2022-06-13T20:29:22Z
seems to be a bug in the DMD backend, does not reproduce with LDC
Comment #4 by d.bugs — 2022-06-13T20:45:05Z
nvm, actually reproduces with ldc as well, so more likely a frontend bug:
ldc2 -main -c -unittest -I. foo.d -of foo.o
ldc2 -lib -ofprotocol.a protocol.d
dmd -oftestlib foo.o protocol.a
For some reason ldc generated extra objects which I accidentally used instead, which were the wrong symbols and didn't cause this linker error.
Comment #5 by robert.schadek — 2024-12-13T19:23:15Z