[Bug 179] Covariance screws up when overriding two interfaces or a class and an interface
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sun Jun 11 14:55:59 PDT 2006
http://d.puremagic.com/bugzilla/show_bug.cgi?id=179
------- Comment #1 from daiphoenix at lycos.com 2006-06-11 16:55 -------
In your example, one can remove the Mother class, and the bug still persists,
like this:
----------------------------------
import std.stdio;
interface Father {
Father test();
void showData();
}
class Child : Father {
int data;
this(int d) { data = d; }
Child test() {
writefln("in CovFunc Test");
return new Child(69);
}
void showData() {
writefln("Child: %d", data);
}
}
void icov2test() {
Child aChild = new Child(42);
aChild.showData();
Father childsDad = aChild;
childsDad.showData();
Father dadTest = childsDad.test;
writefln("FCALL dadTest.showData");
dadTest.showData();
writefln("FCALL dadTest.test");
dadTest.test();
writefln("FCALL (cast(Child) dadTest).showData");
(cast(Child) dadTest).showData();
}
----------------------------------
Here is an even shorter version:
(yes ICov and IFoo could be the same)
----------------------------------
import std.stdio;
interface IFoo {
}
interface ICov {
IFoo test();
}
class Child : ICov, IFoo {
Child covfunc() {
writefln("in CovFunc Test");
return new Child();
}
}
void icov3() {
ICov icov = new Child();
IFoo ifoo = icov.covfunc();
writefln(ifoo.classinfo.name); //Segfault or prints garbage
writefln((cast(Object)ifoo)); //Segfault or prints garbage
}
----------------------------------
Regardless of all that, it is still quite true what you about "Father expects
a Father interface reference and Mother expects an object reference for the
same function - and Child.test cannot be directly compatible with both at the
same time."
I found this feature (allowing class-covariant-with-interface return types
strange since the beggining when it was introduced. Now I'm thinking if this is
feasable at all.
You see, a class is *not* covariant with an (implemented) interface (meaning,
"one can [not] substitute an interface with a class"), they are merely
convertible to one another. Thus a function with a class return type is not
covariant with a function with an interface return type, meaning:
one can not substitute a interface-return-function with a
class-return-function.
The same doesn't happen for truly covariant return types (i.e. with Object --
Foo, one can substitute the functions). This is confirmable by looking at the
asm code.
DMD goes around this with some adaptions, doing transparent conversions, but I
wonder if it is possible (or desirable) to make this work with all corner
cases.
--
More information about the Digitalmars-d-bugs
mailing list