I'm trying to create an inlined try-catch helper function but running into a compilation error due to the return
statement occurring within the inlined lambda. Below is some code demonstrating the same issue
fun isStringEmpty(myString: String): Boolean {
stringOpHelper {
return myString.length == 0
}
}
inline fun <T> stringOpHelper(fn: () -> T) {
println("performing string operation")
fn()
}
This will compile with the desired effect if a return is added after the inlined function call or an exception is thrown, but that code should be unreachable. Eg:
fun isStringEmpty(myString: String): Boolean {
stringOpHelper {
return myString.length == 0
}
TODO("this is actually unreachable")
}
inline fun <T> stringOpHelper(fn: () -> T) {
println("performing string operation")
fn()
}
My expectation was that the compiler would see that stringOpHelper
always calls fn()
and the fn
in isStringEmpty
always returns, so the inlined stringOpHelper
call always returns.
Is it possible to define the inline helper function in a way that avoids the need for the unreachable exception / return in the calling function? Otherwise, what's the reason for why this isn't possible?
There is mechanism for such purposes called contracts, but this feature is experimental and its usage must be marked with @ExperimentalContracts
or @OptIn(ExperimentalContracts::class)
@OptIn(ExperimentalContracts::class)
inline fun <T> stringOpHelper(fn: () -> T) {
contract {
callsInPlace(fn, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
}
println("performing string operation")
fn()
}