Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Found LocalVariables do not refer to a variable with the same name (Kotlin inline function) #1232

Closed
n3o59hf opened this issue Feb 5, 2016 · 5 comments
Assignees
Milestone

Comments

@n3o59hf
Copy link

n3o59hf commented Feb 5, 2016

After updating RoboVM 1.11.0 -> 1.13.0, LibGDX 1.7.1 -> 1.9.1 and Kotlin 1.0.0-beta-2423 -> 1.0.0-rc-1036, iOS compilation started to fail with exception:

[ERROR] Couldn't compile app
java.lang.IllegalStateException: Found LocalVariables do not refer to a variable with the same name: [LocalVariable [name=listener$iv, index=2, startUnit=$stack0 = new com.edibleday.coindrag.scene.CoinOverlay$click$1, endUnit=l6 = $stack0, descriptor=Lkotlin/jvm/functions/Function0;], LocalVariable [name=listener, index=2, startUnit=l0 := @this: com.edibleday.coindrag.scene.CoinOverlay, endUnit=null, descriptor=Lkotlin/jvm/functions/Function0;]]
    at soot.toolkits.scalar.LocalSplitter.findLocalVariables(LocalSplitter.java:325)
    at soot.toolkits.scalar.LocalSplitter.mergeWebs(LocalSplitter.java:258)
    at soot.toolkits.scalar.LocalSplitter.internalTransform(LocalSplitter.java:185)
    at soot.BodyTransformer.transform(BodyTransformer.java:51)
    at soot.Transform.apply(Transform.java:97)
    at soot.JimpleBodyPack.applyPhaseOptions(JimpleBodyPack.java:57)
    at soot.JimpleBodyPack.internalApply(JimpleBodyPack.java:89)
    at soot.Pack.apply(Pack.java:117)
    at soot.coffi.CoffiMethodSource.getBody(CoffiMethodSource.java:115)
    at soot.SootMethod.getBodyFromMethodSource(SootMethod.java:87)
    at soot.SootMethod.retrieveActiveBody(SootMethod.java:321)
    at org.robovm.compiler.plugin.lambda.LambdaPlugin.transformMethod(LambdaPlugin.java:94)
    at org.robovm.compiler.plugin.lambda.LambdaPlugin.beforeClass(LambdaPlugin.java:82)
    at org.robovm.compiler.ClassCompiler.compile(ClassCompiler.java:705)
    at org.robovm.compiler.ClassCompiler.compile(ClassCompiler.java:297)
    at org.robovm.compiler.AppCompiler.compile(AppCompiler.java:301)
    at org.robovm.compiler.AppCompiler.compile(AppCompiler.java:384)
    at org.robovm.compiler.AppCompiler.compile(AppCompiler.java:444)
    at org.robovm.compiler.AppCompiler.build(AppCompiler.java:773)
    at org.robovm.idea.compilation.RoboVmCompilerThread.doCompile(RoboVmCompilerThread.java:53)
    at org.robovm.idea.compilation.RoboVmCompilerThread.run(RoboVmCompilerThread.java:59)

CoinOverlay's method click() and it's only usage (in same class):

    inline fun click(crossinline listener: () -> Unit): ClickListener {
        return object : ClickListener() {
            override fun clicked(event: InputEvent?, x: Float, y: Float) {
                super.clicked(event, x, y)
                listener()
            }
        }
    }

    fun Actor.onClick(listener: () -> Unit) {
        this.addListener(click(listener))
    }

Possibly relevant bytecode:

  public final com.badlogic.gdx.scenes.scene2d.utils.ClickListener click(kotlin.jvm.functions.Function0<kotlin.Unit>);
    Code:
       0: aload_1
       1: ldc_w         #757                // String listener
       4: invokestatic  #231                // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
       7: new           #759                // class com/edibleday/coindrag/scene/CoinOverlay$click$1
      10: dup
      11: aload_1
      12: invokespecial #760                // Method com/edibleday/coindrag/scene/CoinOverlay$click$1."<init>":(Lkotlin/jvm/functions/Function0;)V
      15: checkcast     #762                // class com/badlogic/gdx/scenes/scene2d/utils/ClickListener
      18: areturn

  public final void onClick(com.badlogic.gdx.scenes.scene2d.Actor, kotlin.jvm.functions.Function0<kotlin.Unit>);
    Code:
       0: aload_1
       1: ldc_w         #765                // String $receiver
       4: invokestatic  #231                // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_2
       8: ldc_w         #757                // String listener
      11: invokestatic  #231                // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
      14: aload_1
      15: aload_0
      16: astore_3
      17: astore        5
      19: nop
      20: new           #759                // class com/edibleday/coindrag/scene/CoinOverlay$click$1
      23: dup
      24: aload_2
      25: invokespecial #760                // Method com/edibleday/coindrag/scene/CoinOverlay$click$1."<init>":(Lkotlin/jvm/functions/Function0;)V
      28: checkcast     #762                // class com/badlogic/gdx/scenes/scene2d/utils/ClickListener
      31: astore        6
      33: aload         5
      35: aload         6
      37: checkcast     #767                // class com/badlogic/gdx/scenes/scene2d/EventListener
      40: invokevirtual #771                // Method com/badlogic/gdx/scenes/scene2d/Actor.addListener:(Lcom/badlogic/gdx/scenes/scene2d/EventListener;)Z
      43: pop
      44: return
public final class com.edibleday.coindrag.scene.CoinOverlay$click$1 extends com.badlogic.gdx.scenes.scene2d.utils.ClickListener {
  final kotlin.jvm.functions.Function0 $listener;

  public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent, float, float);
    Code:
       0: aload_0
       1: aload_1
       2: fload_2
       3: fload_3
       4: invokespecial #14                 // Method com/badlogic/gdx/scenes/scene2d/utils/ClickListener.clicked:(Lcom/badlogic/gdx/scenes/scene2d/InputEvent;FF)V
       7: aload_0
       8: getfield      #18                 // Field $listener:Lkotlin/jvm/functions/Function0;
      11: invokeinterface #24,  1           // InterfaceMethod kotlin/jvm/functions/Function0.invoke:()Ljava/lang/Object;
      16: pop
      17: return

  public com.edibleday.coindrag.scene.CoinOverlay$click$1(kotlin.jvm.functions.Function0);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #18                 // Field $listener:Lkotlin/jvm/functions/Function0;
       5: aload_0
       6: invokespecial #36                 // Method com/badlogic/gdx/scenes/scene2d/utils/ClickListener."<init>":()V
       9: return

Same error happens in other places where inline functions are used.

@n3o59hf
Copy link
Author

n3o59hf commented Feb 5, 2016

Minimal test project in attachment.
To reproduce exception, run ./gradlew build launchConsole --stacktrace in terminal (happens in both Linux and MacOS)

inline_clean.zip

Problem.kt:

package com.mycompany.myapp

/**
 * Created by elviss on 16.5.2.
 */


object Main {
    @JvmStatic fun main(args: Array<String>) {

        println(ProblemTest().functionCallingInline { "Hello!" })

    }
}

class ProblemTest {

    inline fun inlineFunction(inlineFunctionArgument: () -> String) = inlineFunctionArgument()
    fun functionCallingInline(normalFunctionArgument: () -> String) = inlineFunction (normalFunctionArgument)
}

Results in exception:

...
java.lang.IllegalStateException: Found LocalVariables do not refer to a variable with the same name: [LocalVariable [name=inlineFunctionArgument$iv, index=1, startUnit=$stack0 = l1, endUnit=return $stack0, descriptor=Lkotlin/jvm/functions/Function0;], LocalVariable [name=normalFunctionArgument, index=1, startUnit=l0 := @this: com.mycompany.myapp.ProblemTest, endUnit=null, descriptor=Lkotlin/jvm/functions/Function0;]]
...

@n3o59hf
Copy link
Author

n3o59hf commented Feb 5, 2016

Issue does not happen with older Kotlin versions (tested with 1.0.0-beta-4589)

@badlogic
Copy link
Contributor

badlogic commented Feb 5, 2016

Awesome, thanks a lot for the repro case. We'll try to have a look asap.

@badlogic badlogic added this to the 1.14 milestone Feb 5, 2016
@badlogic badlogic self-assigned this Feb 5, 2016
@orangy
Copy link

orangy commented Feb 9, 2016

Should be fixed in Kotlin EAP build 1050: bintray.com/kotlin/kotlin-eap/kotlin/1.0.0-rc-1050/view

@badlogic
Copy link
Contributor

badlogic commented Feb 9, 2016

Wow, awesome! Thanks a lot @orangy!

@badlogic badlogic closed this as completed Feb 9, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants