When using templates defined in another module (via an alias), all the files must be compiled together or link errors ensue. For example: Compile together $ dmd main.d mymodule.d && echo "ok" ok Compile separately $ dmd -c main.d && dmd -c mymodule.d && dmd main.o mymodule.o main.o:(.data._D78TypeInfo_S8mymodule40__T15TypedIdentifierVAyaa6_4d7954797065Z15TypedIdentifier6__initZ+0x40): undefined reference to `_D8mymodule40__T15TypedIdentifierVAyaa6_4d7954797065Z15TypedIdentifier8__xopCmpFKxS8mymodule40__T15TypedIdentifierVAyaa6_4d7954797065Z15TypedIdentifierKxS8mymodule40__T15TypedIdentifierVAyaa6_4d7954797065Z15TypedIdentifierZi' main.o:(.data._D78TypeInfo_S8mymodule40__T15TypedIdentifierVAyaa6_4d7954797065Z15TypedIdentifier6__initZ+0x48): undefined reference to `_D8mymodule40__T15TypedIdentifierVAyaa6_4d7954797065Z15TypedIdentifier8toStringMxFZAya' collect2: error: ld returned 1 exit status --- errorlevel 1 This screws up our build system (which builds each file separately) Here is the code for reproducing this error: ============================================= main.d ============================================= import mymodule; void main() { int dict[MyType]; auto x = dict[MyType(0)]; } ============================================= mymodule.d ============================================= module mymodule; import std.string; struct TypedIdentifier(string NAME) { int value; this(int val) { value = val; } int opCmp(ref const int rhs) const { return value > rhs ? 1 : (value < rhs ? -1 : 0); } string toString() const { return format("%s(%s)", NAME, value); } } alias MyType = TypedIdentifier!"MyType";
Further examination shows that it's caused by the automatic addition of function attributes: ================================= $ nm mymodule.o | grep TypedIdentifier | grep toString _D8mymodule40__T15TypedIdentifierVAyaa6_4d7954797065Z15TypedIdentifier8toStringMxFNaNfZAya $ nm main.o | grep TypedIdentifier | grep toString _D8mymodule40__T15TypedIdentifierVAyaa6_4d7954797065Z15TypedIdentifier8toStringMxFZAya ================================= NaNf = pure @safe (according to http://dlang.org/abi.html ) When the `alias` sits in mymodule.d, toString gets qualified with `pure @safe`, while when it's invoked in main.d, it only looks for `const`. If I move the alias into main.d, or just skip the alias and use the full type, everything's fine. This seems like a bug in the alias mechanism of the core compiler.
I guess this is another instance of Issue 10442.
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18813 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB