Code with generics compiles under 1.3.72 but not under 1.4.30

The following code https://pl.kotl.in/B1ul4rhIP compiles and works in 1.3.72, but fails in 1.4.30, why?

import kotlinx.coroutines.*

sealed class CallResult<out T : Any> {
    data class Success<out T : Any>(val data: T) : CallResult<T>()
    data class Failure(val error: String) : CallResult<Nothing>()
}

public data class Response<T>(val body: T?)

suspend fun <T : Any> f1(lambda: suspend () -> Response<T>): T = when(val result = f3(lambda())) {
    is CallResult.Success -> result.data
    is CallResult.Failure -> throw Exception()
}

fun <T : Any> f3(response: Response<T>): CallResult<T> {
    val body = response.body
    if (body != null) {
        return CallResult.Success(body)
    } else {
        return CallResult.Failure("error")
    }
}

fun f4(): Response<Any> {
    return Response(Any())
}

fun main() {
    GlobalScope.launch {
        f1 { f4() }
    }
}

Fun fact: this happens only when it is the last call in a lambda (making it a return result), otherwise it compiles also in 1.4:

    GlobalScope.launch {
        f1 { f4() }
        // adding this line makes it compile in 1.4
        print("test") 
    }

GlobalScope.launch expects lambda whose return type is Unit, but f1 { f4() } returns Any.

@Beholder Are you talking about 1.3.72 or 1.4.30? My question is why one language version compiles and another not…

Besides, I don’t think it is the case since adding <Any> fixes it:

GlobalScope.launch {
	f1<Any> { f4() } // compiles in 1.4.30
}

And, by the way, in the above case the Android Studio incorrectly marks <Any> as “unnecessary and can be removed”, which is wrong.

1 Like

Kotlin 1.4 switched to a new type-inference. In general the new one is faster and better but with a big change like this there is always the danger of corner cases where the new one is not quite as good (yet). You should probably create an issue at https://kotl.in/issue with your case so this can be fixed in the future.

1 Like

You’re right, the answer to my question is that Kotlin actually switched to a new type inference algorithm in the new version, that explains it. I have created an issue - https://youtrack.jetbrains.com/issue/KT-44889 - hopefully this helps the guys to look into it.

2 Likes

Definitely file a bug. I tried to switch our large codebase form 1.3.72 to 1.4 but there were many issues: code which should compile doesn’t and vice versa — code with obvious errors compiles fine — which is much more problematic. I am waiting on False TYPE_MISMATCH introduced in 1.4 : KT-44831 (jetbrains.com) but there are many more. Until 1.4. gets stable I would advise staying on 1.3.72.