Weird error “incompatible types: Set<CAP#1> cannot be converted to Set<Integer>” when calling Kotlin from Java

I have this code which I was able to reduce to the following:

open class Base<T>(val t: T)

class Moo<E>(val e: Set<E>) : Base<Set<E>>(e)

val moo = Moo(setOf(1))

val z: Set<Int> = moo.t     // ok

So far so good, but I wanted to do that last line in Java:

Set<Integer> z = getMoo().getT();

// error: incompatible types: Set<CAP#1> cannot be converted to Set<Integer>
//   where CAP#1 is a fresh type-variable:
//     CAP#1 extends Integer from capture of ? extends Integer

But I’m not doing any wildcards am I? Isn’t E invariant? What’s going on?

Funnily, there error disappears if I define Moo as

class Moo<E, S : Set<E>>(val e: S) : Base<S>(e)
1 Like

In Kotlin, the interface Set is declared as interface Set<out E>. This means that whenever you write Set<SomeType> it is compiled to Set<? extends SomeType>. This is described in further detail here

2 Likes