Compiler fails to recognize exception thrown from when expression

@Throws(RuntimeException::class)
fun boom() {
    throw RuntimeException("Boom!")
}

fun main() {
    val x = 1f
    
    val y = when {
        x < 10 -> {
            if (x % 2 == 0f) {
                boom()
            } else {
                2f
            }
        }
        x >= 10 -> {
            3f
        }
        else -> {
            4f
        }
    }
    
    println(y.toInt())
}

Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public inline fun String.toInt(): Int defined in kotlin.text public inline fun String.toInt(radix: Int): Int defined in kotlin.text private fun Iterable<FlagEnum>.toInt(): Int defined in kotlin.text

boom as a function has a return type of Unit. If you know that a function will never return, you should set it’s return type to Nothing.
https://kotlinlang.org/docs/reference/exceptions.html#the-nothing-type

2 Likes

Excellent, that takes care of the problem. Although, I’d say, it’s not very intuitive, especially given the @Throws annotation already present.

The Throws annotation is there for interop with java’s checked exception system. This explained in the docs.
While I don’t mind explaining stuff you might want to take a look through the reference part of the kotlin docs: https://kotlinlang.org/docs/reference/
It’s a good place to start looking whenever you have problems with basic language constructs. Still, if you can’t find an answer there feel free to ask :wink:

1 Like

@Wasabi375 The docs are a good place to start, but it’s not easy to find answers to specific questions in it, unless you know what you’re looking for.

The @Throws annotation says that the function can throw an exception — not that it always will.

And functions defined as a block always infer a type of Unit unless you specify one.

Now, if the function had been defined as an expression…

2 Likes