ok. I just removed from test.di all non public entities. // D import file generated from 'test.d' module test; public { void foo();
struct Boo { public { void boo(); } } } Now, let's build it: $ dmd test.di test.d main.d test.d: Error: module test from file test.d conflicts with another module test from file test.di di file not specification, but just another version of implementation? ok. let's separate build. $ dmd -c test.d $ dmd main.d test.di main.d(7): Error: no property 'S' for type 'Boo' main.d(7): Error: Boo.S is used as a type main.d(8): Error: undefined identifier HelperStruct It seem like ok. Expected error. We fix it, and everybody happy. But after years, someone changes test.d: module test; public { void foo() {foo_helper();} struct Boo { public: void booBar() {S ss; foo_helper();} // <---- method was renamed private: struct S {}; } } private { struct HelperStruct {}; void foo_helper() {HelperStruct s;} } He rename method, but forgot to change test.di. Let's build it: $ dmd -c test.d $ dmd main.d test.di Undefined symbols for architecture i386: "_D4test3Boo3booMFZv", referenced from: __Dmain in main.o "_D4test3fooFZv", referenced from: __Dmain in main.o ld: symbol(s) not found for architecture i386 collect2: ld returned 1 exit status Oops. No compilation error. Only linker error. Welcome back to C! Compiler doesn't know anything about "specification" files. So, he did't check specification&implementation conformance.