Compiler Internal Error: Couldn't inline method call


#1

The following code produces [Internal Error] org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error on build. I don’t see anything technically wrong with this stripped down code snipped. Am i missing something, or is this actually a compiler bug?

inline fun <T>safe(action: () -> T): T{
    try{
        return action()
    }catch(ex: Exception){
        try{
            action()
        }catch(ignored: Exception){
        }
        throw Exception("failed", ex)
    }finally{
    }
}

fun test(factory: () -> Int): Int{
    safe {
        return factory()
    }
}

fun main(args: Array<String>) {
    val t = test({ 42 })
    println("Hello, $t!")
}

try.kotlinlang.org responds with

Can’t get program output

Error details from IntelliJ with kotlinc-jvm 1.2.31 (JRE 9+181)
Error:Kotlin: [Internal Error] org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: Couldn't inline method call 'safe' into
public fun test(factory: () -> kotlin.Int): kotlin.Int defined in root package in file main.kt
fun test(factory: () -> Int): Int{
    safe {
        return factory()
    }
}
Cause: safe (Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;:
    TRYCATCHBLOCK L0 L1 L2 java/lang/Exception
    TRYCATCHBLOCK L3 L4 L5 java/lang/Exception
    TRYCATCHBLOCK L6 L7 L5 java/lang/Exception
    TRYCATCHBLOCK L3 L4 L8 null
    TRYCATCHBLOCK L6 L9 L8 null
    TRYCATCHBLOCK L10 L11 L8 null
    TRYCATCHBLOCK L12 L13 L8 null
   L14
   L15
    ALOAD 0
    LDC "action"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
   L16
    LINENUMBER 87 L16
   L3
    NOP
   L17
    LINENUMBER 88 L17
    ALOAD 0
    INVOKEINTERFACE kotlin/jvm/functions/Function0.invoke ()Ljava/lang/Object;
    ASTORE 2
   L4
    ICONST_1
    INVOKESTATIC kotlin/jvm/internal/InlineMarker.finallyStart (I)V
   L18
    ICONST_1
    INVOKESTATIC kotlin/jvm/internal/InlineMarker.finallyEnd (I)V
    ALOAD 2
    ARETURN
   L6
   L19
   L7
   L9
    ICONST_1
    INVOKESTATIC kotlin/jvm/internal/InlineMarker.finallyStart (I)V
   L20
    ICONST_1
    INVOKESTATIC kotlin/jvm/internal/InlineMarker.finallyEnd (I)V
    GOTO L21
   L10
   L5
   L22
    LINENUMBER 89 L22
    ASTORE 2
   L23
   L24
    LINENUMBER 90 L24
   L0
    NOP
   L25
    LINENUMBER 91 L25
    ALOAD 0
    INVOKEINTERFACE kotlin/jvm/functions/Function0.invoke ()Ljava/lang/Object;
    POP
   L26
   L1
    GOTO L27
   L2
   L28
    LINENUMBER 92 L28
    ASTORE 3
   L29
   L30
   L31
   L32
    LINENUMBER 93 L32
   L27
   L33
    LINENUMBER 94 L33
    NEW java/lang/Exception
    DUP
    LDC "failed"
    ALOAD 2
    CHECKCAST java/lang/Throwable
    INVOKESPECIAL java/lang/Exception.<init> (Ljava/lang/String;Ljava/lang/Throwable;)V
    CHECKCAST java/lang/Throwable
    ATHROW
   L34
   L35
   L11
    ICONST_1
    INVOKESTATIC kotlin/jvm/internal/InlineMarker.finallyStart (I)V
   L36
    ICONST_1
    INVOKESTATIC kotlin/jvm/internal/InlineMarker.finallyEnd (I)V
    GOTO L21
   L12
   L8
    ASTORE 2
   L13
   L37
    ICONST_1
    INVOKESTATIC kotlin/jvm/internal/InlineMarker.finallyStart (I)V
   L38
    ICONST_1
    INVOKESTATIC kotlin/jvm/internal/InlineMarker.finallyEnd (I)V
   L39
    ALOAD 2
    ATHROW
   L40
    LINENUMBER 96 L40
   L21
   L41
    LINENUMBER 97 L41
    GETSTATIC kotlin/Unit.INSTANCE : Lkotlin/Unit;
    ARETURN
   L42
    LOCALVARIABLE ignored Ljava/lang/Exception; L29 L31 3
    LOCALVARIABLE ex Ljava/lang/Exception; L23 L35 2
    LOCALVARIABLE action Lkotlin/jvm/functions/Function0; L14 L42 0
    LOCALVARIABLE $i$f$safe I L14 L42 1
    MAXSTACK = 4
    MAXLOCALS = 4
Cause: org.jetbrains.org.objectweb.asm.tree.VarInsnNode cannot be cast to org.jetbrains.org.objectweb.asm.tree.LdcInsnNode
File being compiled at position: (100,5) in C:/Users/Faark/Documents/IdeaProjects/kotlinTest/src/main.kt
The root cause was thrown at: inlineCodegenUtils.kt:365
	at org.jetbrains.kotlin.codegen.inline.InlineCodegen.throwCompilationException(InlineCodegen.kt:135)
	at org.jetbrains.kotlin.codegen.inline.InlineCodegen.performInline(InlineCodegen.kt:178)
	at org.jetbrains.kotlin.codegen.inline.PsiInlineCodegen.genCallInner(InlineCodegen.kt:671)
	at org.jetbrains.kotlin.codegen.CallGenerator$DefaultImpls.genCall(CallGenerator.kt:106)
	at org.jetbrains.kotlin.codegen.inline.PsiInlineCodegen.genCall(InlineCodegen.kt:652)
	at org.jetbrains.kotlin.codegen.ExpressionCodegen.invokeMethodWithArguments(ExpressionCodegen.java:2324)
	at org.jetbrains.kotlin.codegen.ExpressionCodegen.invokeMethodWithArguments(ExpressionCodegen.java:2275)
	at org.jetbrains.kotlin.codegen.Callable$invokeMethodWithArguments$1.invoke(Callable.kt:44)
	at org.jetbrains.kotlin.codegen.Callable$invokeMethodWithArguments$1.invoke(Callable.kt:23)
	at org.jetbrains.kotlin.codegen.OperationStackValue.putSelector(StackValue.kt:75)
	at org.jetbrains.kotlin.codegen.StackValueWithLeaveTask.putSelector(StackValue.kt:67)
	at org.jetbrains.kotlin.codegen.StackValue.put(StackValue.java:105)
	at org.jetbrains.kotlin.codegen.StackValue.put(StackValue.java:98)
	at org.jetbrains.kotlin.codegen.ExpressionCodegen.putStackValue(ExpressionCodegen.java:354)
	at org.jetbrains.kotlin.codegen.ExpressionCodegen.gen(ExpressionCodegen.java:339)
	at org.jetbrains.kotlin.codegen.ExpressionCodegen.returnExpression(ExpressionCodegen.java:1590)
	at org.jetbrains.kotlin.codegen.FunctionGenerationStrategy$FunctionDefault.doGenerateBody(FunctionGenerationStrategy.java:58)
	at org.jetbrains.kotlin.codegen.FunctionGenerationStrategy$CodegenBased.generateBody(FunctionGenerationStrategy.java:78)
	at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethodBody(FunctionCodegen.java:569)
	at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethodBody(FunctionCodegen.java:332)
	at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethod(FunctionCodegen.java:298)
	at org.jetbrains.kotlin.codegen.FunctionCodegen.generateMethod(FunctionCodegen.java:176)
	at org.jetbrains.kotlin.codegen.FunctionCodegen.gen(FunctionCodegen.java:147)
	at org.jetbrains.kotlin.codegen.MemberCodegen.genSimpleMember(MemberCodegen.java:210)
	at org.jetbrains.kotlin.codegen.PackagePartCodegen.generateBody(PackagePartCodegen.java:95)
	at org.jetbrains.kotlin.codegen.MemberCodegen.generate(MemberCodegen.java:142)
	at org.jetbrains.kotlin.codegen.PackageCodegenImpl.generateFile(PackageCodegenImpl.java:127)
	at org.jetbrains.kotlin.codegen.PackageCodegenImpl.generate(PackageCodegenImpl.java:66)
	at org.jetbrains.kotlin.codegen.DefaultCodegenFactory.generatePackage(CodegenFactory.kt:97)
	at org.jetbrains.kotlin.codegen.DefaultCodegenFactory.generateModule(CodegenFactory.kt:68)
	at org.jetbrains.kotlin.codegen.KotlinCodegenFacade.doGenerateFiles(KotlinCodegenFacade.java:47)
	at org.jetbrains.kotlin.codegen.KotlinCodegenFacade.compileCorrectFiles(KotlinCodegenFacade.java:39)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.generate(KotlinToJVMBytecodeCompiler.kt:454)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:150)
	at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:161)
	at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:63)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:108)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:52)
	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:92)
	at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$$inlined$ifAlive$lambda$1.invoke(CompileServiceImpl.kt:389)
	at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$$inlined$ifAlive$lambda$1.invoke(CompileServiceImpl.kt:97)
	at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:909)
	at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:97)
	at org.jetbrains.kotlin.daemon.common.DummyProfiler.withMeasure(PerfUtils.kt:137)
	at org.jetbrains.kotlin.daemon.CompileServiceImpl.checkedCompile(CompileServiceImpl.kt:939)
	at org.jetbrains.kotlin.daemon.CompileServiceImpl.doCompile(CompileServiceImpl.kt:908)
	at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:387)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:355)
	at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
	at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:567)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:800)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:682)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:681)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
	at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.ClassCastException: org.jetbrains.org.objectweb.asm.tree.VarInsnNode cannot be cast to org.jetbrains.org.objectweb.asm.tree.LdcInsnNode
	at org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getConstant(inlineCodegenUtils.kt:365)
	at org.jetbrains.kotlin.codegen.inline.InternalFinallyBlockInliner.findFinallyBlockBody(InternalFinallyBlockInliner.java:452)
	at org.jetbrains.kotlin.codegen.inline.InternalFinallyBlockInliner.processInlineFunFinallyBlocks(InternalFinallyBlockInliner.java:169)
	at org.jetbrains.kotlin.codegen.inline.InternalFinallyBlockInliner.processInlineFunFinallyBlocks(InternalFinallyBlockInliner.java:81)
	at org.jetbrains.kotlin.codegen.inline.MethodInliner.doInline(MethodInliner.kt:118)
	at org.jetbrains.kotlin.codegen.inline.MethodInliner.doInline(MethodInliner.kt:71)
	at org.jetbrains.kotlin.codegen.inline.InlineCodegen.inlineCall(InlineCodegen.kt:289)
	at org.jetbrains.kotlin.codegen.inline.InlineCodegen.performInline(InlineCodegen.kt:169)
	... 62 more

#2

the reason why it doesn’t work, I don’t know, but about your implementation, don’t you mean:

fun test(factory: () -> Int) = safe {
    factory()
}

As your return says to return from test instead of the lambda you passed to safe.
Ps. If I catched your intention correctly, you can put crossinline in front of your lambda-parameter, such that so called non-local returns aren’t even allowed.


#3

Usually internal compiler error is a result of some bug, so you can report that right to our tracker: http://kotl.in/issue


#4

Empty finally section causes confusion to compiler. But do you really need it?