ceylon / ceylon-compiler

DEPRECATED
GNU General Public License v2.0
138 stars 36 forks source link

yet another bug related to refining type arguments of supertypes #1643

Open gavinking opened 10 years ago

gavinking commented 10 years ago

This code:

class XX() satisfies Scalar<XX>&Comparable<XX|YY> {
    compare(XX|YY other) => nothing;
    divided(XX other) => nothing;
    float => nothing;
    fractionalPart => nothing;
    integer => nothing;
    magnitude => nothing;
    negated => nothing;
    negative => nothing;
    plus(XX other) => nothing;
    plusInteger(Integer integer) => nothing;
    positive => nothing;
    sign => nothing;
    times(XX other) => nothing;
    timesInteger(Integer integer) => nothing;
    wholePart => nothing;
}

class YY() satisfies Scalar<YY>&Comparable<XX|YY> {
    compare(XX|YY other) => nothing;
    divided(YY other) => nothing;
    float => nothing;
    fractionalPart => nothing;
    integer => nothing;
    magnitude => nothing;
    negated => nothing;
    negative => nothing;
    plus(YY other) => nothing;
    plusInteger(Integer integer) => nothing;
    positive => nothing;
    sign => nothing;
    times(YY other) => nothing;
    timesInteger(Integer integer) => nothing;
    wholePart => nothing;
}

Results in:

Name clash: compare(ceylon.language.Comparable) in foo.XX and compare(Other) in ceylon.language.Comparable have the same erasure, yet neither overrides the other

This bug blocks ceylon/ceylon.language#453.

lucaswerkmeister commented 10 years ago

Here’s updated code after Scalar was merged with Number (ceylon/ceylon.language#452):

class XX() satisfies Number<XX>&Comparable<XX|YY> {
    compare(XX|YY other) => nothing;
    divided(XX other) => nothing;
    fractionalPart => nothing;
    magnitude => nothing;
    negated => nothing;
    negative => nothing;
    plus(XX other) => nothing;
    plusInteger(Integer integer) => nothing;
    positive => nothing;
    sign => nothing;
    times(XX other) => nothing;
    timesInteger(Integer integer) => nothing;
    wholePart => nothing;
    powerOfInteger(Integer integer) => nothing;

}

class YY() satisfies Number<YY>&Comparable<XX|YY> {
    compare(XX|YY other) => nothing;
    divided(YY other) => nothing;
    fractionalPart => nothing;
    magnitude => nothing;
    negated => nothing;
    negative => nothing;
    plus(YY other) => nothing;
    plusInteger(Integer integer) => nothing;
    positive => nothing;
    sign => nothing;
    times(YY other) => nothing;
    timesInteger(Integer integer) => nothing;
    wholePart => nothing;
    powerOfInteger(Integer integer) => nothing;
}

And here’s much shorter code by making the classes abstract:

abstract class XX() satisfies Number<XX>&Comparable<XX|YY> {
    compare(XX|YY other) => nothing;
}

abstract class YY() satisfies Number<YY>&Comparable<XX|YY> {
    compare(XX|YY other) => nothing;
}
tombentley commented 10 years ago

Once we've fixed the declaration there's another issue with call sites:

void use(XX xx, XX|YY xy) {
    variable value c = xx <=> xy;
}

We currently do not downcast the Object xy argument to Comparable, so javac fails.

tombentley commented 10 years ago

This is going to be too hard to fix in the remaining time for 1.1, and the thing it's blocking (https://github.com/ceylon/ceylon.language/issues/453) is not for 1.1, so let's defer it for now.