kuza
kuza

Reputation: 3041

Kotlin/JVM compiler fails over conditional function refrences

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

Answers (1)

gidds
gidds

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

Related Questions