[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