Consider the overloaded function foo
:
fun foo(i: Int) { /* */ }
fun foo(i_s: Collection<Int>) { /* */ }
I get an overload resolution ambiguity error with the following code:
val bar = foo(Stream.empty<Int>().collect(Collectors.toList()))
Overload resolution ambiguity:
public fun foo(i: Int): Unit defined in ...
public fun foo(i_s: Collection): Unit defined in ...
As far as I can tell the resolution should be clear: I am collecting the stream to a list, so the foo(Collection<Int>)
should be taken. Some more experiments suggest a failure to resolve the generics correctly, so:
I tested a few other things: foo(listOf())
does not error, neither does
val bar = Stream.empty<Int>().collect(Collectors.toList())
val baz = foo(bar)
Replacing toList()
with toSet()
does not alter the behavior, but toCollection { ArrayList<Int>() }
compiles in all cases.
If I change foo
to fun <T> foo(i_s: Collection<T>)
, the error changes to
Type inference failed. Expected type mismatch: inferred type is (Mutable)List! but Int was expected
This opens more questions for me:
Looks like this is a bug in the old inference algorithm, because it works correctly with the new inference. I filed an issue in the Kotlin bug tracker, at least for adding a regression test. You can follow it for updates.
More information on new inference:
https://youtrack.jetbrains.com/issue/KT-31507
https://blog.jetbrains.com/kotlin/2019/06/kotlin-1-3-40-released/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With