Abstract interfaces and covariant return types
Brought to you by:
bonniot
Code:
package test;
import nice.functional;
class Test implements Foo
{
Test[] children;
}
more(Test t) = generator(t.children);
abstract interface Foo
{
}
<Foo T> () -> T more(T t);
Compiler error:
Incorrect return type:
Found : ()->test.Test
Expected: ()->T
This appears not to always fail. For example if I replace the implementation with
more(Test t) = () => t;
The code compiles fine.
I've not been able to narrow down exactly what circumstances it fails in.
Logged In: YES
user_id=1681313
Originator: YES
As pointed out by arjanb in #nice, if you replace 'implements Foo' with 'finally implements Foo', this starts working. I still think it's a bug though. :-)
Logged In: YES
user_id=1681313
Originator: YES
Ok. It's not a bug - it's just a somewhat unhelpful error message and a slightly confusing feature.
The problem is of course that if I subclass Test, say Test2 extends Test, then the type parameter will be incorrect as more(Test2) will return a () => Test, so the method would need overriding (I'm not sure why the compiler doesn't just force you to override the method, but maybe there's some good reason for it). If we say "Test finally implements Foo" then this forces the type parameter T to never be bound below Test, so the problem doesn't come up.