Skip to content

Kotlin Inject interop: crash when using val for provides #1571

@gabrielittner

Description

@gabrielittner

Description

Having something like the following in Kotlin Inject with interop enabled will result in Metro failing:

public val ImplementationType.bind: BoundType
    @Provides get() = this

Exception:

e: java.lang.IllegalStateException: Expected 2 arguments but got 1 for function: dev.zacsweers.metro.sample.KotlinInjectTest.SimpleComponent.<get-bind>
        at dev.zacsweers.metro.compiler.ir.IrKt.irInvoke(ir.kt:339)
        at dev.zacsweers.metro.compiler.ir.IrKt.irInvoke$default(ir.kt:294)
        at dev.zacsweers.metro.compiler.ir.transformers.BindingContainerTransformer.implementCreatorBodies$lambda$1(BindingContainerTransformer.kt:553)
        at dev.zacsweers.metro.compiler.ir.transformers.FactoryIrUtilKt.generateStaticNewInstanceFunction(factoryIrUtil.kt:151)
        at dev.zacsweers.metro.compiler.ir.transformers.BindingContainerTransformer.implementCreatorBodies(BindingContainerTransformer.kt:528)
        at dev.zacsweers.metro.compiler.ir.transformers.BindingContainerTransformer.getOrLookupProviderFactory(BindingContainerTransformer.kt:347)
        at dev.zacsweers.metro.compiler.ir.transformers.BindingContainerTransformer.visitProperty(BindingContainerTransformer.kt:234)
        at dev.zacsweers.metro.compiler.ir.transformers.BindingContainerTransformer.findContainer(BindingContainerTransformer.kt:163)
        at dev.zacsweers.metro.compiler.ir.transformers.BindingContainerTransformer.findContainer$default(BindingContainerTransformer.kt:132)
        at dev.zacsweers.metro.compiler.ir.transformers.DependencyGraphTransformer.visitClassNew(DependencyGraphTransformer.kt:179)
        at org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext.visitClass(IrElementTransformerVoidWithContext.kt:62)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:57)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:19)
        at org.jetbrains.kotlin.ir.declarations.IrClass.accept(IrClass.kt:72)
        at org.jetbrains.kotlin.ir.IrElementBase.transform(IrElementBase.kt:33)
        at org.jetbrains.kotlin.ir.util.TransformKt.transformInPlace(transform.kt:35)
        at org.jetbrains.kotlin.ir.declarations.IrClass.transformChildren(IrClass.kt:82)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitDeclaration(IrElementTransformerVoid.kt:40)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:54)
        at org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext.visitClassNew(IrElementTransformerVoidWithContext.kt:126)
        at dev.zacsweers.metro.compiler.ir.transformers.DependencyGraphTransformer.visitClassNew(DependencyGraphTransformer.kt:183)
        at org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext.visitClass(IrElementTransformerVoidWithContext.kt:62)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:57)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:19)
        at org.jetbrains.kotlin.ir.declarations.IrClass.accept(IrClass.kt:72)
        at org.jetbrains.kotlin.ir.IrElementBase.transform(IrElementBase.kt:33)
        at org.jetbrains.kotlin.ir.util.TransformKt.transformInPlace(transform.kt:35)
        at org.jetbrains.kotlin.ir.declarations.IrPackageFragment.transformChildren(IrPackageFragment.kt:31)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitPackageFragment(IrElementTransformerVoid.kt:146)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitFile(IrElementTransformerVoid.kt:160)
        at org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext.visitFileNew(IrElementTransformerVoidWithContext.kt:122)
        at org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext.visitFile(IrElementTransformerVoidWithContext.kt:55)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitFile(IrElementTransformerVoid.kt:163)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitFile(IrElementTransformerVoid.kt:19)
        at org.jetbrains.kotlin.ir.declarations.IrFile.accept(IrFile.kt:27)
        at org.jetbrains.kotlin.ir.declarations.IrFile.transform(IrFile.kt:30)
        at org.jetbrains.kotlin.ir.declarations.IrFile.transform(IrFile.kt:19)
        at org.jetbrains.kotlin.ir.util.TransformKt.transformInPlace(transform.kt:35)
        at org.jetbrains.kotlin.ir.declarations.IrModuleFragment.transformChildren(IrModuleFragment.kt:46)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitModuleFragment(IrElementTransformerVoid.kt:102)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitModuleFragment(IrElementTransformerVoid.kt:107)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitModuleFragment(IrElementTransformerVoid.kt:19)
        at org.jetbrains.kotlin.ir.declarations.IrModuleFragment.accept(IrModuleFragment.kt:36)
        at org.jetbrains.kotlin.ir.declarations.IrModuleFragment.transform(IrModuleFragment.kt:39)
        at dev.zacsweers.metro.compiler.ir.MetroIrGenerationExtension.generateInner(MetroIrGenerationExtension.kt:71)
        at dev.zacsweers.metro.compiler.ir.MetroIrGenerationExtension.generate(MetroIrGenerationExtension.kt:44)
        at org.jetbrains.kotlin.fir.pipeline.ConvertToIrKt.applyIrGenerationExtensions(convertToIr.kt:498)
        at org.jetbrains.kotlin.fir.pipeline.Fir2IrPipeline.runActualizationPipeline(convertToIr.kt:253)
        at org.jetbrains.kotlin.fir.pipeline.Fir2IrPipeline.convertToIrAndActualize(convertToIr.kt:134)
        at org.jetbrains.kotlin.fir.pipeline.ConvertToIrKt.convertToIrAndActualize(convertToIr.kt:100)
        at org.jetbrains.kotlin.fir.pipeline.ConvertToIrKt.convertToIrAndActualize$default(convertToIr.kt:73)
        at org.jetbrains.kotlin.cli.jvm.compiler.legacy.pipeline.JvmCompilerPipelineKt.convertToIrAndActualizeForJvm(jvmCompilerPipeline.kt:101)
        at org.jetbrains.kotlin.cli.pipeline.jvm.JvmFir2IrPipelinePhase.executePhase(JvmFir2IrPipelinePhase.kt:30)
        at org.jetbrains.kotlin.cli.pipeline.jvm.JvmFir2IrPipelinePhase.executePhase(JvmFir2IrPipelinePhase.kt:25)
        at org.jetbrains.kotlin.cli.pipeline.jvm.JvmFir2IrPipelinePhase.executePhase(JvmFir2IrPipelinePhase.kt:19)
        at org.jetbrains.kotlin.cli.pipeline.PipelinePhase.phaseBody(PipelinePhase.kt:68)
        at org.jetbrains.kotlin.cli.pipeline.PipelinePhase.phaseBody(PipelinePhase.kt:58)
        at org.jetbrains.kotlin.config.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:102)
        at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:22)
        at org.jetbrains.kotlin.config.phaser.CompilerPhaseKt.invokeToplevel(CompilerPhase.kt:53)
        at org.jetbrains.kotlin.cli.pipeline.AbstractCliPipeline.runPhasedPipeline(AbstractCliPipeline.kt:109)
        at org.jetbrains.kotlin.cli.pipeline.AbstractCliPipeline.execute(AbstractCliPipeline.kt:68)
        at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecutePhased(K2JVMCompiler.kt:79)
        at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecutePhased(K2JVMCompiler.kt:45)
        at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:90)
        at org.jetbrains.kotlin.cli.common.CLICompiler.exec(CLICompiler.kt:352)
        at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunnerBase.runCompiler(IncrementalJvmCompilerRunnerBase.kt:176)
        at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunnerBase.runCompiler(IncrementalJvmCompilerRunnerBase.kt:39)
        at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.doCompile(IncrementalCompilerRunner.kt:499)
        at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileImpl(IncrementalCompilerRunner.kt:416)
        at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileNonIncrementally(IncrementalCompilerRunner.kt:301)
        at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:128)
        at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:684)
        at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:94)
        at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1810)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
        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:714)
        at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:598)
        at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:844)
        at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:721)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
        at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:720)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
        at java.base/java.lang.Thread.run(Thread.java:1575)

Self-contained Reproducer

main...gabrielittner:metro:kotlin-inject-bining-issue

Metro version

0.9.2

Context

I've seen a mention in the differences docs that mentions the get() = this not being necessary with Metro, but I couldn't find a mention that this is not supported for interop. Having it supported would be great, so that we don't need to convert all of these to functions initially (and then back to val with @Binds when we actually start using Metro's annotations). If it won't be supported, it would be nice to at least have a proper error message.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions