May 14, 2017
https://issues.dlang.org/show_bug.cgi?id=17398

          Issue ID: 17398
           Summary: Partial template struct instantiation with __FILE__
                    leading to link error
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: jbc.engelen@gmail.com

File a.d:
```
module a;

import c;

S!int a;

void main() {}
```

File c.d:
```
module c;

import a;

enum BUG = true; // `false` "removes" the bug by reordering,
                 // but this does not work in the original failing code.

struct S(F)
{
    void templateTaking__FILE__(string file = __FILE__)() {
    }

    static if (BUG) {
        auto addrFoo() {
            return &foo;
        }
    }

    private void foo() {
        templateTaking__FILE__();
    }

    static if (!BUG) {
        auto addrFoo() {
            return &foo;
        }
    }
}

S!int cInst;
```

When these two files are compiled separately, the following link error occurs: ```
> dmd -c /Users/johan/weka/ldc/build39release/tests/c.d -of=c.o dmd /Users/johan/weka/ldc/build39release/tests/a.d c_dmd.o
Undefined symbols for architecture x86_64:

"_D1c8__T1STiZ1S128__T22templateTaking__FILE__VAyaa46_2f55736572732f6a6f68616e2f77656b612f6c64632f6275696c64333972656c656173652f74657374732f632e64Z22templateTaking__FILE__MFNaNbNiNfZv",
referenced from:
      _D1c8__T1STiZ1S3fooMFNaNbNiNfZv in c.o

"_D1c8__T1STiZ1S41__T22templateTaking__FILE__VAyaa3_632e64Z22templateTaking__FILE__MFNaNbNiNfZv",
referenced from:
      _D1c8__T1STiZ1S3fooMFNaNbNiNfZv in a.o
```

The reason for the link error is that parts of `S!int` are instantiated in c.o and other parts in a.o. When compiling c.o, __FILE__ in templateTaking__FILE__ is c.d's absolute path. When compiling a.o however, c.d is an import and __FILE__ in templateTaking__FILE__ is c.d's relative path.

The circular import results in some S!int things being instantiated in a.o but partly (it refers to the templateTaking__FILE__!<relative path> symbol). Interestingly, reordering of the functions in struct S "fixes" this issue.

This issue is another example of troubles with __FILE__ as a template parameter. __FILE_FULL_PATH__ would resolve this.

But, this issue also highlights a template instantiation problem: part of the template instantiated in a.o, but it should either be fully instantiated or not at all. The "partly instantiated" is causing the troubles. If the template struct was fully instantiated, there would be template bloat, yes, but there would not be linker errors.

Tested with dmd 2.074.0 and dmd 2.072.2. (LDC has the same problem)

--