This might be related to http://d.puremagic.com/issues/show_bug.cgi?id=1978
I added Frank and Lars to the CC in case they are interested.
Basically, I think it has to do with a class implementing two interfaces that inherit from the same base interface.
This might be a minimal example:
extern(C) int printf(char*,...);
interface A(V)
{
int foo();
}
interface B(K, V) : A!(V)
{
alias A!(V).foo foo; // needed or else A isn't examined to resolve foo()
int foo(int x);
}
interface C(K, V) : B!(K, V)
{
}
interface D(K, V) : A!(V), C!(K, V)
{
alias C!(K, V).foo foo; // needed or else A is used to resolve foo
int bar();
}
class E(K, V) : C!(K, V)
{
int foo() {printf("foo\n"); return 0;}
int foo(int x) {printf("foo(int)\n"); return 0;}
int bar() {printf("bar\n"); return 0;}
}
void main() {
C!(uint, uint) c = new D!(uint, uint);
c.foo();
c.foo(0);
c.bar();
}
outputs:
foo
bar
bar
The following change to interface D seems to resolve the issue:
interface D(K, V) : C!(K, V), A!(V)
{
int bar();
}
However, there might be cases where this kind of solution is not possible.
Comment #1 by schveiguy — 2008-11-24T08:46:43Z
sheesh, I think I have messed up the example.
Please replace the definition for class E, and the main function with this:
class E(K, V) : D!(K, V)
{
int foo() {printf("foo\n"); return 0;}
int foo(int x) {printf("foo(int)\n"); return 0;}
int bar() {printf("bar\n"); return 0;}
}
void main() {
D!(uint, uint) d = new E!(uint, uint);
d.foo();
d.foo(0);
d.bar();
}
Comment #2 by schveiguy — 2008-12-09T11:43:55Z
Bumped into this again, with a simpler inheritance tree.
extern(C) int printf(char*,...);
interface A
{
char a();
}
interface B
{
char b();
}
interface C : A, B
{
char c();
}
interface D
{
char d();
}
interface E : C, D
{
char e();
}
class Foo : E
{
char a() { return('a'); }
char b() { return('b'); }
char c() { return('c'); }
char d() { return('d'); }
char e() { return('e'); }
}
void main() {
auto foo = new Foo;
E e = foo; D d = foo; C c = foo; B b = foo; A a = foo;
printf("Foo: %c %c %c %c %c\n", foo.a, foo.b, foo.c, foo.d, foo.e);
printf("A: %c\n", a.a);
printf("B: %c\n", b.b);
printf("C: %c %c %c\n", c.a, c.b, c.c);
printf("D: %c\n", d.d);
printf("E: %c %c %c %c %c\n", e.a, e.b, e.c, e.d, e.e);
}
outputs:
Foo: a b c d e
A: a
B: b
C: a b c
D: d
E: a a c d e
Note the incorrect E line.
If I swap around E's base interfaces, so E now becomes:
interface E : D, C
{
char e();
}
Now the E line is still wrong:
Foo: a b c d e
A: a
B: b
C: a b c
D: d
E: d b c d e
Marking as a blocker. I don't know how to work around this.
Comment #3 by rsinfu — 2009-05-14T20:50:40Z
*** Issue 2758 has been marked as a duplicate of this issue. ***
Comment #4 by rsinfu — 2009-05-14T21:10:49Z
Created attachment 367
This patch should fix the issue.
There is a typo in class.c. The compiler generates wrong vtable due to the typo.
Comment #5 by schveiguy — 2009-05-15T06:56:20Z
Which compiler version is your patch against? According to the changelog, 1.045 fixed this issue. I haven't had time to test it yet, you may want to compare your patch against that fix.