Why does crossinline break the return in this inline function?
The lambda passed to executeAction uses a return to break out of the loop. The author wants that return to keep working. Decide whether crossinline belongs here and fix the signature accordingly.
inline fun executeAction(crossinline action: () -> Unit) {
action()
}
fun someFun() {
executeAction {
for (i in 0..10) {
if (i == 5) return
}
}
}
Find and fix the bug.
crossinline forbids a non-local return from the lambda, but this code relies on one — the return exits someFun. With crossinline it would not compile. Remove crossinline: plain inline already inlines action and permits the non-local return.
- ✗Reading
crossinlineas a harmless optimisation rather than a ban on non-local return - ✗Thinking the
returnonly exits the lambda, socrossinlinechanges nothing - ✗Adding
noinlineto fix it, which also disables inlining of the lambda
- →In what situation would you actually need
crossinlineon this parameter? - →What is the difference between
crossinlineandnoinline?
The bug
crossinline marks a lambda parameter as one that may not use a non-local return. But someFun relies on exactly that — the return inside the lambda is meant to exit someFun. With crossinline the compiler rejects that return, so the code does not compile.
inline fun executeAction(crossinline action: () -> Unit) {
action()
}
fun someFun() {
executeAction {
for (i in 0..10) {
if (i == 5) return // ❌ forbidden under crossinline
}
}
}
The fix
Remove crossinline. Plain inline inlines action directly into someFun, so the non-local return is allowed and exits someFun.
inline fun executeAction(action: () -> Unit) {
action()
}
fun someFun() {
executeAction {
for (i in 0..10) {
if (i == 5) return // ✅ exits someFun
}
}
}
crossinline is only needed when the inlined lambda is invoked from another execution context (a nested lambda, an anonymous object) where a non-local return would be illegal.