ceylon / ceylon-js

DEPRECATED
Apache License 2.0
54 stars 9 forks source link

method type parameter strangeness #547

Closed jvasileff closed 9 years ago

jvasileff commented 9 years ago

This program:

interface SuperContainer<Element> {}
interface SubContainer<Element> satisfies SuperContainer<Element> {}

interface SuperFactory satisfies Identifiable {
    shared formal SuperContainer<X> newList<X>();
}

class SubFactory() satisfies SuperFactory {
    shared actual SubContainer<Y> newList<Y>()
        =>  object satisfies SubContainer<Y> {};
}

shared
void run() {
    SubFactory sub = SubFactory();
    SuperFactory sup = sub;

    assert(sub === sup);

    Anything subInstance = sub.newList<String>();
    print(subInstance is SubContainer<String>);
    print(subInstance is SuperContainer<String>);

    Anything supInstance = sup.newList<String>();
    print(supInstance is SubContainer<String>);
    print(supInstance is SuperContainer<String>);
}

outputs:

true
true
false
false

but should output four trues. Values produced by sub and sup should have the same runtime types since sub === sup.

A few items to note:

interface Obj<T> {}

interface Sup satisfies Identifiable {
    shared formal Obj<X> newList<X>();
}

class Sub() satisfies Sup {
    shared actual Obj<Y> newList<Y>()
        =>  object satisfies Obj<Y> {};
}

shared
void run() {
    Sub sub = Sub();
    Sup sup = sub;

    Anything subInstance = sub.newList<String>();
    Anything supInstance = sup.newList<String>();

    print(subInstance is Obj<String>); // true    
    print(supInstance is Obj<String>); // false
}
chochos commented 9 years ago

sup.newList<String>() passes String to the X type parameter, but there's no such thing in the refined implementation (it's Y, that's why the error goes away if the type parameter has the same name in the refined method).

A "quick" fix would be checking if the type parameter is refined, and if it has a different name from the super declaration, then check for both names in the type arguments. It will bloat the code, but the alternative is to look for the super declarations at runtime...

chochos commented 9 years ago

I found a nicer solution, I just have to test it against a deeper hierarchy

chochos commented 9 years ago

BTW variance had nothing to do with this, it was about missing type arguments. So the second, shorter, example is the one I'll use as official test.