eclipse-archived / ceylon

The Ceylon compiler, language module, and command line tools
http://ceylon-lang.org
Apache License 2.0
395 stars 62 forks source link

unexpected coverage error w/use-site variance and self type #7414

Closed jvasileff closed 5 years ago

jvasileff commented 5 years ago

The expression v of Supertype fails below:

interface I<T> of T {}

void run(I<String> s) {
    I<out Anything> s1 = s; // ok
    I<in Nothing> s2 = s;   // ok

    value s11 = s of I<out Anything>; // error 1
    value s22 = s of I<in Nothing>;   // error 2
}

// error1: specified type does not cover the cases of the operand expression:
// 'I<out Anything>' does not cover 'I<String>'

// error2: specified type does not cover the cases of the operand expression:
// 'I<in Nothing>' does not cover 'I<String>'
gavinking commented 5 years ago

Oh, wait, I see, this I<String> is a pretty nonsensical type. At least, it's unpopulated.

gavinking commented 5 years ago

Fixed, thanks.

jvasileff commented 5 years ago

Oh, wait, I see, this I is a pretty nonsensical type. At least, it's unpopulated.

Ah, yeah, bad example since String is final. There's also:

interface J {}
interface I<T> of T {}

void run(I<J> s) {
    I<out Anything> s1 = s; // ok
    I<in Nothing> s2 = s;   // ok

    value s11 = s of I<out Anything>; // error 1
    value s22 = s of I<in Nothing>;   // error 2
}
jvasileff commented 5 years ago

The patch allows:

interface J {}
interface I<T> of T {}
class C() satisfies J & I<J> {}
class D() {}

shared void run() {
    I<J> c = C();
    D s = c of D; // error: java.lang.ClassCastException: simple.C cannot be cast to simple.D
}

(Or more directly, the expression (C() of I<J>) of Nothing)

gavinking commented 5 years ago

@jvasileff nice catch. But v2 of the patch, which I was already in the works when you posted, seems to have fixed that problem too. But anyway I'll add it as a test.

gavinking commented 5 years ago

I would say this is fixed now.