Java interop: Conflicting overloads despite @JvmSynthetic


#1

I have the requirements for lambdas that can throw in Java consumers. Since Function0 etc. don’t allow that, we have a custom @FunctionalInterface:
ThrowingProducer.java:

@FunctionalInterface
public interface ThrowingProducer<T> {
    @Nullable T run() throws Exception;
}

The following overloaded functions are part of one of our base test classes:

Interface.kt:

@JvmSynthetic // seems to be ineffective
fun <T> doAsAdmin(action: () -> T): T = doAsAdmin(ThrowingProducer { action() })
fun <T> doAsAdmin(action: ThrowingProducer<T>): T = ...

Java call site: doAsAdmin(()->"")

Compiler error:

error: reference to doAsAdmin is ambiguous
        doAsAdmin(() -> "");
        ^
  both method <T#1>doAsAdmin(Function0<? extends T#1>) in BaseClassImplementingInterfaceKt and method <T#2>doAsAdmin(ThrowingProducer<T#2>) in BaseClassImplementingInterfaceKt match
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in method <T#1>doAsAdmin(Function0<? extends T#1>)
    T#2 extends Object declared in method <T#2>doAsAdmin(ThrowingProducer<T#2>)

Appearently, @JvmSynthetic does not make the function invisible to Java.
I’m using Kotlin 1.3 and Java 8.


#2

Hello, I couldn’t reproduce the problem with the following dummy code (Kotlin 1.3.10):

// ThrowingProducer.java

import org.jetbrains.annotations.Nullable;

@FunctionalInterface
public interface ThrowingProducer<T> {
    @Nullable
    T run() throws Exception;

    public static void main(String[] args) {
        (new A()).foo(()->"");
    }
}

// main.kt

class A {
    @JvmSynthetic
    fun <T> foo(action: () -> T) = foo(ThrowingProducer { action() })

    fun <T> foo(action: ThrowingProducer<T>) {
        println("foo")
    }
}

Can you please share a sample project and submit an issue here: http://kotl.in/issue ? Thanks.