trait Measure[-C, M]
implicit object PathMeasure extends Measure[Long, (Int, Long)]
object FingerTree {
def empty[V, A](implicit m: Measure[A, V]): FingerTree[V, A] = ???
}
trait FingerTree[V, +A] {
def :+[A1 >: A](b: A1)(implicit m: Measure[A1, V]): FingerTree[V, A1]
}
trait Test {
def readPathComponent(): Long
def read(sz: Int): Any = {
var tree = FingerTree.empty(PathMeasure) // problem origin
var i = 0
while (i < sz) {
tree = tree :+ readPathComponent() // problem shows here
i += 1
}
???
}
}
In the line 'problem shows here':
Found: Long
Required: Nothing
Thus var tree has type FingerTree[?, Nothing] instead of FingerTree[(Int, Long), Long]
Should not infer Nothing (no problem in Scala 2.13)
Minimized further, without implicits:
trait Foo[+A] {
def foo[A1 >: A](a: A1): Foo[A1]
}
trait Bar[-B]
trait X {
def bla[A](m: Bar[A]): Foo[A]
def baz(x: Bar[Int]): Unit = {
var t = bla(x)
t = t.foo(0)
}
}
[info] Compiling 1 Scala source to /src/dotty-issues/i9842/target/scala-0.27/classes ...
[error] -- [E007] Type Mismatch Error: /src/dotty-issues/i9842/src/main/scala/Main.scala:12:14
[error] 12 | t = t.foo(0)
[error] | ^
[error] | Found: (0 : Int)
[error] | Required: Nothing
Compilation succeeds with Scala 2.13.3.
These are as intended. Scala 2 has a built-in "fear of Nothing": That is, it will never infer Nothing and will instead infer the upper bound. That leads to other problems when Nothing is the right type to infer and is an irregular exception. Scala 3 does not special-case Nothing in this way anymore. In
var t = bla(x)
The best type to infer for t is indeed Foo[Nothing]. If you want a wider type, you have to annotate the var.