Reputation: 3041
I am a bit puzzled about compilation error over this sample piece of code:
inline fun String.report(to: (String) -> Unit) = to(this)
fun report(message:String, logger: Logger?=null): (AsyncResult<*>) -> Unit = {
when (it.succeeded()) {
true -> "$message constructed".report(logger?::info ? ::print)
false -> "$message crashed because: ${it.cause()}".report(logger?::error ? ::print)
}
}
When I try to compile I get org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: Failed to generate expression: KtLambdaExpression
It seems like I cannot pick a function reference conditionally for an example:
val problem: (String) -> Unit = (logger?::info ?::print) as (String) -> Unit
will lead to a similar compilation exception: Failed to generate expression: KtCallableReferenceExpression
Is it me doing it wrong or perhaps a limitation of the Kotlin compiler?
My environment is:
Kotlin plugin version 1.3.60-release-IJ2019.2-1
IntelliJ IDEA 2019.2.4 (Ultimate Edition)
Build #IU-192.7142.36, built on October 29, 2019
Runtime version: 11.0.4+10-b304.77 x86_64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
macOS 10.14.6
Update:KT-35075
Thanks to the suggestion of the @gidds, I can get function reference that approaches messes Kotlin compiler null-ability resolution. Have a look:
val method : (String) -> Unit = if (logger != null) logger!!::info else ::print
Yes, I do get a warning for the redundant not-null assertion (!!
operator) saying:
Unnecessary non-null assertion (!!) on a non-null receiver of type Logger
But without it, compiler refuses to compile saying:
Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Logger?
Upvotes: 0
Views: 461
Reputation: 18597
Both the type of exception (in a JetBrains internal package, org.jetbrains.…) and the message (‘…Internal error…’) indicate that this is a bug in the compiler. So it's JetBrains' problem, not directly your fault.
The best thing to do is to raise it with JetBrains, on their tracking system: https://youtrack.jetbrains.com/ (First checking whether someone else has already raised this issue there.)
It may be indirectly your fault, for trying to compile code that happens to hit that bug. That's often because your code is invalid somehow, though not necessarily.
In this case, I'm confused by your use of the expression:
logger?::info ?::print
Kotlin has no ?
or ?::
operator, so I'm not sure what you intend there. Perhaps you'd have more luck with something along the lines of:
if (logger != null) logger::info else ::print
Upvotes: 1