JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
16.15k stars 1.17k forks source link

[Web] fun interface with composable function crashes compiler #2688

Closed arkivanov closed 1 month ago

arkivanov commented 1 year ago

Compose: 1.3.0 Kotlin: 1.8.0

Code:

fun main() {
    onWasmReady {
        Window("Sample") {
            getFoo().Foo()
        }
    }
}

@Composable
fun getFoo(): Foo =
    Foo {}

fun interface Foo {
    @Composable
    fun Foo()
}

Error:

org.jetbrains.kotlin.backend.common.CompilationException: Back-end: Please report this problem https://kotl.in/issue
/Users/arkivanov/dev/workspace/Decompose/sample/app-js-compose/src/jsMain/kotlin/com/arkivanov/decompose/sample/app/Main.kt:32:1
Problem with `@Composable
@DecoyImplementation(name = "getFoo$composable", id = -7124660374465924303L)
@DecoyImplementationDefaultsBitMask(bitMask = 0)
fun getFoo$composable(/* var */ $composer: Composer?, $changed: Int): Foo {
  var $composer: Composer? = $composer
  { // BLOCK
    $composer.startReplaceableGroup(key = -285628594)
    sourceInformation(composer = $composer, sourceInformation = "C(getFoo$composable)")
  }
  when {
    isTraceInProgress() -> traceEventStart(key = -285628594, dirty1 = $changed, dirty2 = -1, info = "com.arkivanov.decompose.sample.app.getFoo$composable (Main.kt:31)")
  }
  val tmp0: Foo = ComposableSingletons$MainKt.<get-lambda-2>() /*-> Foo */
  when {
    isTraceInProgress() -> traceEventEnd()
  }
  $composer.endReplaceableGroup()
  return tmp0
}

`
Details: Internal error in body lowering: java.lang.IllegalArgumentException: Sequence contains more than one matching element.
    at org.jetbrains.kotlin.backend.common.lower.SingleAbstractMethodLowering.createObjectProxy(SingleAbstractMethodLowering.kt:380)
    at org.jetbrains.kotlin.backend.common.lower.SingleAbstractMethodLowering.visitTypeOperator(SingleAbstractMethodLowering.kt:119)
    at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitTypeOperator(IrElementTransformerVoid.kt:261)
    at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitTypeOperator(IrElementTransformerVoid.kt:24)
    at org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall.accept(IrTypeOperatorCall.kt:30)
    at org.jetbrains.kotlin.ir.expressions.IrExpression.transform(IrExpression.kt:28)
    at org.jetbrains.kotlin.ir.declarations.IrVariable.transformChildren(IrVariable.kt:44)
    at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitDeclaration(IrElementTransformerVoid.kt:57)
    at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitVariable(IrElementTransformerVoid.kt:101)
    at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitVariable(IrElementTransformerVoid.kt:102)
    at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitVariable(IrElementTransformerVoid.kt:24)
    at org.jetbrains.kotlin.ir.declarations.IrVariable.accept(IrVariable.kt:37)
    at org.jetbrains.kotlin.ir.IrElementBase.transform(IrElementBase.kt:24)
    at org.jetbrains.kotlin.ir.util.TransformKt.transformInPlace(transform.kt:35)
    at org.jetbrains.kotlin.ir.expressions.IrBlockBody.transformChildren(IrBlockBody.kt:31)
    at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoidKt.transformChildrenVoid(IrElementTransformerVoid.kt:346)
    at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.transformChildrenVoid(IrElementTransformerVoid.kt:341)
    at org.jetbrains.kotlin.ir.backend.js.lower.JsSingleAbstractMethodLowering.lower(JsSingleAbstractMethodLowering.kt:44)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor$visitBody$1.invoke(Lower.kt:190)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor$visitBody$1.invoke(Lower.kt:189)
    at org.jetbrains.kotlin.ir.backend.js.WholeWorldStageController.restrictTo(WholeWorldStageController.kt:29)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor.visitBody(Lower.kt:189)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor.visitBody(Lower.kt:168)
    at org.jetbrains.kotlin.ir.visitors.IrElementVisitor$DefaultImpls.visitBlockBody(IrElementVisitor.kt:163)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor.visitBlockBody(Lower.kt:168)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor.visitBlockBody(Lower.kt:168)
    at org.jetbrains.kotlin.ir.expressions.IrBlockBody.accept(IrBlockBody.kt:24)
    at org.jetbrains.kotlin.ir.declarations.IrFunction.acceptChildren(IrFunction.kt:53)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor.visitDeclaration(Lower.kt:177)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor.visitDeclaration(Lower.kt:168)
    at org.jetbrains.kotlin.ir.visitors.IrElementVisitor$DefaultImpls.visitFunction(IrElementVisitor.kt:112)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor.visitFunction(Lower.kt:168)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor.visitFunction(Lower.kt:168)
    at org.jetbrains.kotlin.ir.visitors.IrElementVisitor$DefaultImpls.visitSimpleFunction(IrElementVisitor.kt:139)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor.visitSimpleFunction(Lower.kt:168)
    at org.jetbrains.kotlin.backend.common.BodyLoweringVisitor.visitSimpleFunction(Lower.kt:168)
    at org.jetbrains.kotlin.ir.declarations.IrSimpleFunction.accept(IrSimpleFunction.kt:36)
    at org.jetbrains.kotlin.backend.common.LowerKt.runOnFilePostfix(Lower.kt:147)
    at org.jetbrains.kotlin.backend.common.LowerKt.runOnFilePostfix$default(Lower.kt:140)
    at org.jetbrains.kotlin.backend.common.BodyLoweringPass.lower(Lower.kt:62)
    at org.jetbrains.kotlin.ir.backend.js.lower.JsSingleAbstractMethodLowering.lower(JsSingleAbstractMethodLowering.kt:35)
    at org.jetbrains.kotlin.backend.common.LowerKt.lower(Lower.kt:75)
    at org.jetbrains.kotlin.ir.backend.js.JsLoweringPhasesKt$makeJsModulePhase$1.invoke(JsLoweringPhases.kt:36)
    at org.jetbrains.kotlin.ir.backend.js.JsLoweringPhasesKt$makeJsModulePhase$1.invoke(JsLoweringPhases.kt:35)
    at org.jetbrains.kotlin.ir.backend.js.JsLoweringPhasesKt$makeCustomJsModulePhase$1.invoke(JsLoweringPhases.kt:59)
    at org.jetbrains.kotlin.ir.backend.js.JsLoweringPhasesKt$makeCustomJsModulePhase$1.invoke(JsLoweringPhases.kt:51)
    at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
    at org.jetbrains.kotlin.ir.backend.js.CompilerWithICKt.lowerPreservingTags(compilerWithIC.kt:76)
    at org.jetbrains.kotlin.ir.backend.js.JsIrCompilerWithIC.compile(compilerWithIC.kt:59)
    at org.jetbrains.kotlin.ir.backend.js.ic.CacheUpdater.compileDirtyFiles(CacheUpdater.kt:676)
    at org.jetbrains.kotlin.ir.backend.js.ic.CacheUpdater.actualizeCaches(CacheUpdater.kt:727)
    at org.jetbrains.kotlin.cli.js.K2JsIrCompiler.doExecute(K2JsIrCompiler.kt:300)
    at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:183)
    at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:72)
    at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:101)
    at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:47)
    at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
    at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1645)
    at jdk.internal.reflect.GeneratedMethodAccessor103.invoke(Unknown Source)
    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:359)
    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(AccessController.java:691)
    at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
    at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
    at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.IllegalArgumentException: Sequence contains more than one matching element.
    ... 74 more
eymar commented 1 year ago

The bug is also reproducible with compose 1.2.0 (kotlin 1.7.10), 1.2.2 (kotlin 1.7.20)

okushnikov commented 3 months ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.