[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