Dotty 如何决定如何 infer/when 扩大联合类型?

How does Dotty decide how to infer/when to widen Union Types?

已经讨论了扩大联合类型here,但我似乎找不到以下情况的答案

让我们先看看下面的内容

val x = List(1, 2, "a")

这个异构列表被推断为 List[Any] 就像在 Scala 2 中一样

然而下面

val x2 = List(List(1, 2), Vector("a", "b"))

被推断为List[scala.collection.immutable.AbstractSeq[Int | String]]

这是相当令人困惑的行为。为什么两种不相交类型的 LUB 在一种情况下被推断为 Any 而在另一种情况下推断为联合类型?

如果这只是一个设计决定,是否有任何应该注意的此类情况?

smarter

we avoid inferring union types for the same reason we avoid inferring singleton types, because sometimes they're "too precise"

我对这句话的解释是,将 List(1,2) 键入 List[Int] 而不是 List[1 | 2] 或将 List(new Cat, new Dog) 键入 List[Animal] 更有意义共 List[Cat | Dog].

另请参阅相关 question(我的)

的 Dmytro 评论

Quote from guillaume.martres.me/talks/dotty-tutorial/#/1/13 (slide 15 "Type inference and union types"): "By default, Dotty does not infer union types, they are approximated by a non-union supertype. Union types can be "too precise" and prevent legitimate code from compiling"

另请参阅 23:38 中提到的谈话“Dotty 和类型:到目前为止的故事”。

然而,根据 smarter:

,并集的扩大仅执行 一次 以避免无限的 LUB

when we do the widening once, the resulting type might have a union somewhere (like the example in the section Join of a union type in the doc), we won't widen that if we did do the widening recursively, we could get an infinite lub indeed