ceylon icon indicating copy to clipboard operation
ceylon copied to clipboard

explicting type of shortcut refinement in anyonymous class inside generic function causes error

Open ghost opened this issue 7 years ago • 4 comments

Consider:

abstract class Bla<A>()
{
    shared formal A a;
}

Anything foo<out Bar>(Bla<Bar> bar) => object
    extends Bla<Bla<Bar>>()
{
    a => bar;
};

This compiles without error. However, expliciting the type of a in the inline anonymous class causes an error:

abstract class Bla<A>()
{
    shared formal A a;
}

Anything foo<out Bar>(Bla<Bar> bar) => object
    extends Bla<Bla<Bar>>()
{
    shared actual Bla<Bar> a => bar;
};

The error happens whenever Bar is not invariant.

ghost avatar Jan 22 '18 19:01 ghost

The error elided by @Zambonifofex on the explicit type Bla<Bar> is:

covariant ('out') type parameter 'Bar' of 'foo' occurs at a contravariant or invariant location in type: 'Bla<Bar>'

In theory, I think, Bar should be treated as invariant despite the out annotation. The type checker is currently inconsistent on this:

  1. extends Bla<Bla<Bar>>() is allowed; Bar is treated as invariant in extends, but
  2. as reported, Bla<Bar> in shared actual Bla<Bar> a => bar; is disallowed, treating Bar as covariant
  3. there's also an error if foo's return type is changed to Bla<Bla<Bar>> (Bla<out Bla<out Bar>> is allowed)

jvasileff avatar Jan 22 '18 20:01 jvasileff

In theory, I think, Bar should be treated as invariant despite the out annotation.

Yes, I agree. The method foo() doesn't define any sort of type schema, so there's absolutely no reason to check the variance of occurrences of any of its type parameters, AFAICT.

gavinking avatar Apr 19 '18 00:04 gavinking

This should be rather easy to fix. On the other hand, it's not a very severe problem.

gavinking avatar Apr 19 '18 00:04 gavinking

Vaguely related to #4386, I suppose.

gavinking avatar Apr 23 '18 08:04 gavinking