Issue 2500 - template struct methods are left unresolved if imported from multiple modules
Summary: template struct methods are left unresolved if imported from multiple modules
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: Walter Bright
URL:
Keywords: link-failure, pull
: 12099 (view as issue list)
Depends on:
Blocks:
 
Reported: 2008-12-08 20:08 UTC by Koroskin Denis
Modified: 2015-06-09 05:11 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Koroskin Denis 2008-12-08 20:08:05 UTC
The smallest test case I could find that fails for both D1 and D2 follows:

module A;

import B;
import C;

public class A
{
    T!(A) c;
}

void main()
{
    A a = new A();
    a.c.foo();
}

// B.d
module B;

import A;
import C;

class B
{
    T!(A) t;
}

// C.d
module C;

struct T(Type)
{
    void foo(){}
}

If anyone knows a workaround *please* let me know.
Comment 1 Koroskin Denis 2008-12-08 23:44:59 UTC
Oopps, I forgot to add some importannt information...

The compilation command sequence I used is:
# dmd a -c // ok
# dmd b -c // ok
# dmd c -c // ok
# dmd a.obj b.obj c.obj // link error

Error 42: Symbol Undefined _D1C12__T1TTC1A1AZ1T3fooMFZv
--- errorlevel 1
Comment 2 Steven Schveighoffer 2008-12-09 08:30:02 UTC
Confirmed on Linux as well.

Note that the following commands work ok:

dmd A.d B.d C.d

or

dmd -c A.d B.d C.d
dmd A.o B.o C.o

It seems that in the first (without -c), the symbol is defined in A.o

In the second case, now B.o has the symbol defined, whereas if you compile B.d separate, it is not defined.  There is definitely a bug if compiling the files into objects separately generates different code than compiling them in to objects in one line.
Comment 3 Walter Bright 2008-12-11 02:17:33 UTC
What's happening is A.d thinks that T!(int) is instantiated by B, and B thinks it is instantiated in A. (T!(A) can be T!(int), the A just confuses things.) The workaround is:

1. compile A and B on the same command, instead of separately.

2. structure A and B so they don't import each other.
Comment 4 Walter Bright 2008-12-25 04:39:50 UTC
Fixed dmd 1.038 amd 2.022
Comment 5 Bill Baxter 2009-01-07 18:11:50 UTC
Fix was reverted in 1.039 because it was causing hideously slow compile times for some code.
Comment 6 Kenji Hara 2015-02-05 05:59:45 UTC
The test case still fails to compile with 2.066.1.

https://github.com/D-Programming-Language/dmd/pull/4384
Comment 7 Kenji Hara 2015-02-05 10:01:14 UTC
*** Issue 12099 has been marked as a duplicate of this issue. ***
Comment 8 github-bugzilla 2015-02-13 22:03:23 UTC
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/5ba40267bb26f5405e829112933d1d4e5c179d61
fix Issue 2500 - template struct methods are left unresolved if imported from multiple modules

https://github.com/D-Programming-Language/dmd/commit/c4387428c034ae83fa2504379c68ed3ac354d58f
Merge pull request #4384 from 9rnsr/fix2644

Issue 2644 & 2500 & 10920 - Unresolved template reference