Skip to content

Type inference incorrect w.r.t. variance #471

Open
@Jolanrensen

Description

@Jolanrensen

There are some errors in the type inference of KTypes in DataFrame that make it behave differently compared to the Kotlin Compiler.

For instance, given

interface AbstractType<T>
listOf<AbstractType<Int>>() + listOf<AbstractType<Any>>() // == List<AbstractType<out Any>>

whereas DF would make it List<AbstractType<Any>>, ignoring the out-variance.

Similarly,

listOf<List<Int>>() + listOf<List<List<Any>>>() // == List<List<Any>>

whereas DF would make it List<List<out Any>>, adding an out-variance which is not necessary.

DataFrame is the most incorrect is with in-variance:

listOf<AbstractType<in Int>>() + listOf<AbstractType<Any>>() // == List<AbstractType<in Int>>

yet, DF reports this as List<AbstractType<Any>>, which is just wrong.

This behavior is mostly regulated by Iterable<KType?>.commonType() and Iterable<KType>.commonTypeListifyValues().

We need proper KType unification which takes variance into account when merging types respecting the Kotlin Specification.
Specifically, given two KTypeProjections, we need to be able to give the union/least upper bound/OR, and the intersection/greatest lower bound/AND. I don't know if there already exists a library that provides this logic, as understanding this part of the spec and recreating it is difficult to say the least.
The only similar place where this is done is actually inside the Kotlin compiler itself using ConeKotlinType and ConeTypeProjection instead of KType and KTypeProjection, but I'm not sure this can be reused.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingresearchThis requires a deeper dive to gather a better understanding

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions