kotlincompiler-errors

Why this function causes compile time error and other no? [Only removed function return part]


I have two functions called letItPlay and letItPlay2 just one difference between them is letItPlay2's return type not exist and compiler gives error. I assumed that the default return type is Unit and letItPlay's return type is Unit too so because of those I also assumed that two function's return type are the same. But compiler gives error. Why?

fun letItPlay(where: String = "Home",
                whn: Long,
                how: Float = 3.4f,
                what: Any,
                time: Int = 1,
                quality: Double): Unit = run {
                    return Unit
}

fun letItPlay2(where: String = "Home", // Error: Return type 'Nothing' needs to be specified explicitly.
                whn: Long,
                how: Float = 3.4f,
                what: Any,
                time: Int = 1,
                quality: Double) = run {
                    return Unit // Error: Return type mismatch: expected 'kotlin. Nothing', actual 'kotlin. Unit'.
}

Note: I know that both two functions are weird because of inline functions, but okay, then why are/aren't both to give error and only one gives?


Solution

  • run { return Unit } doesn't make sense. In this case, return Unit is not acting on the lambda passed to run. It is returning the whole letItPlay2 function.

    You intended to write return@run Unit instead, and this compiles as expected.

    return Unit itself is an expression of type Nothing. Therefore, { return Unit } is considered to be a closure that returns Nothing. The final expression in a closure is what that closure will return. To reiterate, return Unit is returning letItPlay2, not the closure, so the compiler considers it as merely just an expression.

    This is in the same way that { 5 } is a closure returns Int, and { throw Exception() } is a closure that returns Nothing (throw expressions are also of type Nothing).

    Therefore, run returns Nothing and letItPlay2 is inferred to return Nothing. As a design choice, Kotlin mandates that the return type Nothing must be specified explicitly, so this gives you the error at letItPlay2. You are returning Unit which is not compatible with Nothing, and this gives you the error at Unit.