Kotlin 错误的类型推断导致重载解析不明确

Kotlin bad type inference gives overload resolution ambiguity

考虑重载函数foo:

fun foo(i: Int) { /* */ }
fun foo(i_s: Collection<Int>) { /* */ }

我收到以下代码的重载解析歧义错误:

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 ...

据我所知,解决方案应该很明确:我正在将流收集到列表中,因此应该采用 foo(Collection<Int>)。一些更多的实验表明未能正确解析泛型,因此:

  1. 为什么泛型解析在这种情况下会失败?
  2. 这 "flaw" 是否在某处记录?这是我应该报告的错误吗?

我测试了一些其他的东西:foo(listOf()) 没有错误,

也没有
val bar = Stream.empty<Int>().collect(Collectors.toList())
val baz = foo(bar)

toSet() 替换 toList() 不会改变行为,但 toCollection { ArrayList<Int>() } 在所有情况下都能编译。

如果我将 foo 更改为 fun <T> foo(i_s: Collection<T>),错误将更改为

Type inference failed. Expected type mismatch: inferred type is (Mutable)List! but Int was expected

这为我打开了更多问题:

  1. 如果我将中间结果存储在变量中,为什么解析会起作用?毕竟,它的类型也是自动解析的?
  2. 类型推断错误是什么意思?为什么会发生?

看起来这是旧推理算法中的一个错误,因为它可以正确地与新推理一起工作。我在 Kotlin 错误跟踪器中提交了一个 issue,至少是为了添加回归测试。可以关注更新哦

有关新推理的更多信息:

https://youtrack.jetbrains.com/issue/KT-31507

https://blog.jetbrains.com/kotlin/2019/06/kotlin-1-3-40-released/