I think I’m seeing variance handled incorrectly by...
# ksp
e
I think I’m seeing variance handled incorrectly by KSP, but could use a sanity check. For the built in
List<out T>
it should be covariant, and javac processors view it that way, but KSP reports the argument as invariant. I have a repro using xprocessing. I don’t think it is a problem within xProcessing because the debugger shows the originating
KSTypeImpl
to have an invariant argument
Copy code
@Test
    fun testListVariance() {
        val libSource = Source.kotlin(
            "lib.kt",
            """
            class KotlinClass {
                fun foo(list: List<CharSequence>) {}
            }
            """.trimIndent()
        )
        runProcessorTest(listOf(libSource)) { invocation ->
            val clazz = invocation.processingEnv.requireTypeElement("KotlinClass")
            val param = clazz.getDeclaredMethods().single().parameters.single()

            if (invocation.isKsp) {
                expectThat(param.type.typeName.toString())
                    .isEqualTo("java.util.List<java.lang.CharSequence>")
            } else {
                expectThat(param.type.typeName.toString())
                    .isEqualTo("java.util.List<? extends java.lang.CharSequence>")
            }
        }
    }
The KSTypeImpl in KSP showing the argument as invariant
j
looks a bug to me
t
Could be related or not, but why it is
java.util.List
, instead of
kotlin.collections.List
?
On the other hand, could it be that
param.type.typeName.toString()
prints use-site variance instead of declaration-site variance?
j
in this case it should respect the declaration site variance.
t
The KSTypeImpl also looks good to me; The argument is invariant.
j
if you try to write List<in T>, compiler will complain about conflicting variance.
e
why it is 
java.util.List
, instead of 
kotlin.collections.List
That’s the JavaPoet TypeName representation that xprocessing exposes. Since it is for java codegen it converts kotlin instrinsics to the java equivalent writing
List<out CharSequence>
gives a warning because
List
already marks its type as
out
. so the type should always be covariant - it is inherited
t
Kotlin allows variance annotations to appear in both declaration and use sites. Type arguments (need to) hold use-site variances, instead of the combined (projected) information from type parameters. It is more like a difference in how Kotlin and Java models variance than a bug.
e
thanks for explaining. I see now that if I dig deeper into the type class I can access the declaration and the type arguments, which show the original type argument
E
as covariant. It seems like a bug with XProcessing then, so I’ll file there
reported at https://issuetracker.google.com/issues/204415667 in case anyone else runs into this. Thanks a lot for the help!
😃 1
t
I think it should be feasible to write a small util to convert Kotlin variances into Java wildcards on top of KSP's API. Please let us know if you see any issues implementing it or feel it better to be implemented in KSP.