If I made an unannotated plugin that 1. Found and ...
# compiler
m
If I made an unannotated plugin that 1. Found and wrapped all
{/* ... */}
lambda literals in a call to
id
, 2. And errored if a lambda was of type
T.(/* ... */) -> R
(ie had a receiver), Could I avoid any and all runtime costs by making
id
an
inline
function?
Copy code
class Builder {
    fun build () {/* ... */}
}

fun run(f: Builder.() -> Unit) {/* ... */}
I want to make it so that •
run { builder -> }
works right out of the box, • And
run { this.build() }
and
run { build() }
are outright prohibited at compile time, Throughout the codebase except for all third party dependencies.
Copy code
inline fun <T> id(arg: T): T {
    return arg
}
This would be the definition of
id
. I want to wrap every lambda in a call to it because in version 2.4, •
run { builder -> }
errors at compile time, but •
run(id { builder -> })
compiles and works as expected.
y
Sadly, I don't think that'd avoid that problem. However, you can likely just remove the
id
calls in the IR backend, and that should likely make it compile. Also, it's good to note that non-local returns would not work with your plugin
m
@Youssef Shoaib [MOD] Sorry, avoid what problem? Also what do you mean I could remove the
id
calls to make it compile? They’re necessary to make it compile. Also why would nonlocal returns not work?
Copy code
fun f() {
    run { builder -> return }
}
The plugin would transform the above into
Copy code
fun f() {
    run(id { builder -> return })
}
y
Apologies, I had just woken up and my brain wasn't fully functioning lol! I meant that making it
inline
won't fix the performance problem that you're mentioning. Kotlin compilation consists of the frontend and the backend. The
id
calls are necessary for the code to pass thru the frontend, but once you're in the backend, the world is your oyster, so you can remove the
id
calls then, and regain the benefits of inlining. Re: non-local returns: if you try the transformed code, you'd see that it doesn't compile! When a lambda is cast as a generic type, it cannot contain non-local returns. This is something that the new lifetime KEEP would solve, but I wouldn't expect that to make it to the language anytime soon
m
@Youssef Shoaib [MOD] No worries, I appreciate you having a look at my questions! I expected the plugin to run before the type checker and thus also before any optimisation passes, which is where I assumed
inline
functions would be inlined. Exactly which part of this understanding is incorrect? Also, I’m used to not having nonlocal returns, so enabling
run { builder -> }
is absolutely worth that cost to me.