out_D=/tmp/ dmd=$dmd_069_X # dmd=$dmd_068_X # dmd=$ldc_X $dmd -c -of$out_D/main.o main.d && nm $out_D/main.o | grep ' U _D4main8__' For dmd v2.071.1 and dmd v2.069, we these undefined symbols; the ones starting with _D4main8_ should not be undefined: U _D15TypeInfo_Struct6__vtblZ U _D4main8__T1AThZ1A8__T1BThZ1B5emptyMFNaNbNdNiNfZi U _D4main8__T1AThZ1A8__T1BThZ1B5frontMFNaNbNiNfZPv U _D4main8__T1AThZ1A8__T1BThZ1B8popFrontMFNaNbNiNfZv U __d_arraybounds U __d_assert U __d_assert_msg U __d_unittest eg, _D4main8__T1AThZ1A8__T1BThZ1B5frontMFNaNbNiNfZPv corresponds to: pure nothrow @nogc @safe void* main.A!(ubyte).A.B!(ubyte).B.front() For ldc (based on DMD v2.071.1 and LLVM 3.8.0) and dmd dmd v2.068, we get the correct undefined symbols: U _D15TypeInfo_Struct6__vtblZ U __d_arraybounds U __d_assert U __d_assert_msg U __d_unittest ---- fun.d: ---- import main; void fun(A!(ubyte) a){ } main.d: ---- module main; import fun; struct A(T) { void test() { foreach (v; this) { } } auto range() { return B!T(); } int opApply(int delegate(T)) { auto r = range; foreach (v; r) { } return 0; } struct B(T) { auto front() { void* a; return a; } @property empty() { return 0; } void popFront() { } } } alias Au = A!(ubyte);
NOTE: this is very bad because it prevents separate compilation model. this removes the undefined symbols: $dmd -c -of$out_D/main.o main.d fund.d this has undefined symbols: $dmd -c -of$out_D/main.o main.d $dmd -c -of$out_D/fun.o fun.d _D4main8__T1AThZ1A8__T1BThZ1B5frontMFNaNbNiNfZPv is undefined in both main.o and fun.o
Does it work if you compile with -allinst ?
(In reply to Walter Bright from comment #2) > Does it work if you compile with -allinst ? no, IIRC I had tried and that didn't work.
(In reply to Timothee Cour from comment #0) > out_D=/tmp/ > > dmd=$dmd_069_X > # dmd=$dmd_068_X > # dmd=$ldc_X > > $dmd -c -of$out_D/main.o main.d && nm $out_D/main.o | grep ' U _D4main8__' > > For dmd v2.071.1 and dmd v2.069, we these undefined symbols; the ones > starting with _D4main8_ should not be undefined: > > U _D4main8__T1AThZ1A8__T1BThZ1B5emptyMFNaNbNdNiNfZi > U _D4main8__T1AThZ1A8__T1BThZ1B5frontMFNaNbNiNfZPv > U _D4main8__T1AThZ1A8__T1BThZ1B8popFrontMFNaNbNiNfZv I see those in fun.o: > nm fun.o 0000000000000000 t 0000000000000000 V __bzeroBytes U _D15TypeInfo_Struct6__vtblZ 0000000000000000 V _D25TypeInfo_S4main__T1AThZQf6__initZ 0000000000000000 V _D35TypeInfo_S4main__T1AThZQf__T1BThZQf6__initZ 0000000000000000 R _D3fun12__ModuleInfoZ 0000000000000000 W _D3funQeFS4main__T1AThZQfZv 0000000000000000 W _D4main__T1AThZQf4testMFNaNbNiNfZv 0000000000000000 W _D4main__T1AThZQf4testMFZ14__foreachbody1MFNaNbNiNfhZi 0000000000000000 W _D4main__T1AThZQf5rangeMFNaNbNiNfZSQBh__TQBfThZQBl__T1BThZQf 0000000000000000 W _D4main__T1AThZQf7opApplyMFNaNbNiNfDFhZiZi 0000000000000000 W _D4main__T1AThZQf__T1BThZQf5emptyMFNaNbNdNiNfZi 0000000000000000 W _D4main__T1AThZQf__T1BThZQf5frontMFNaNbNiNfZPv 0000000000000000 W _D4main__T1AThZQf__T1BThZQf8popFrontMFNaNbNiNfZv U _d_dso_registry U __start_minfo U __stop_minfo with the current master. I'm going to resolve it as WORKSFORME. If it shows up again, we can revisit it.