I'm experimenting with method overloading by lambd...
# language-evolution
d
I'm experimenting with method overloading by lambda return type which needs to enabled by the
@OverloadResolutionByLambdaReturnType
annotation. So while this works as expected (prints
0
)
Copy code
@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
fun test(a: () -> Int) = a() + 1

@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
fun test(a: () -> String) = a()

test { "0" }
changing the signature of the second overload to
fun test(a: () -> Any)
makes the code no longer compiling (with type mismatch error) . Is this something which can be potentially fixed?
a
you could create a specific
fun interface
provider for each argument type. It's a little more verbose but I think it achieves what you want https://pl.kotl.in/0jrPgiu89
d
This unfortunately doesn't solve my problem. Changing
fun interface MyStringProvider : MyProvider<Any>
leads to the same issue as in my version.
a
ah I see, sorry I missed that!
d
I've found relevant info in the spec: https://kotlinlang.org/spec/overload-resolution.html#choosing-the-most-specific-candidate-from-the-overload-candidate-set. See the last example in the section:
Copy code
@OverloadResolutionByLambdaReturnType
fun foo(cb: (Unit) -> String) = Unit // (1)

@OverloadResolutionByLambdaReturnType
fun foo(cb: (Unit) -> CharSequence) = Unit // (2)

fun testError02() {
    // Error: required String, found CharSequence
    foo { a ->
        val a: CharSequence = "42"
        a
    }
    // Both (1) and (2) are applicable
    // (1) is the only most specific candidate
    //   We do not attempt refinement by the lambda return type
}
Seems that the current limitation is intended. Probably the compiler would be too complex otherwise.