Recently, we observed that the type of a type pattern inside a match block is different to what we expected.
Let’s consider the following match block:
val a: A
a match {
x: B => ...
}
In Scala 2.12.6, the type of x
appears to be A with B
now. We would have expected it to be B
and we also understand the standard like this: https://scala-lang.org/files/archive/spec/2.12/08-pattern-matching.html#typed-patterns.
This can also be tested in the following minified example:
trait A { def a: Int }
trait B { def b: Int }
val c: A with B = ???
c match {
case x: B =>
x.a
}
In Scala 2.12.6, this code compiles, while in Dotty it fails with a compile error (a
is not a member of B
).
Generally, the feature of mixing outer and inner type appears useful to me, as it allows to omit type refinements like in this example:
val a: Seq[Int] = ???
a match {
case x: List[_] => x.head: Int
}
But it also means that a match block behaves quite differently to a PartialFunction
.
So is this a bug in the specification or in the implementation?
And what’s the plan with this in Dotty? To me it sounds like in Dotty this would even make more sense as in Scala 2.12 as with
is commutative and mixes in types better.