Open
Description
Compiler version
Dotty 3.2.2 on Scastie as well as Dotty 3.3.0-RC3 locally. Seems to exist from Scala 2.
Minimized code
class T[A]
val x: T[T[_]] = new T[T[_]]
def f(): Unit = x match {
case y: T[T[a]] => ()
}
Output
Compiles.
Expectation
Type error at the pattern y: T[T[a]]
, which should not be allowed in a match on a value of type T[T[_]]
. Conceptually, the pattern just doesn't make sense. (What is a
supposed to be binding? It's clear for x: T[_]
, but not for x: T[T[_]]
.) In a less minimal case of the same kind of pattern, there is an unsoundness:
case class PEndo[X](x: X, f: X => X) {
def next: X = f(x)
}
case class Pair[X](x: X, y: X)
val p = Pair[PEndo[_]](PEndo[String]("42", x => x + x), PEndo[Int](42, x => x + x))
// p: Pair[PEndo[_]], which means each element of the pair may have a different element type ("X")
val ohno: PEndo[_] = p match {
case p: Pair[PEndo[a]] => PEndo(p.x.x, p.x.f andThen p.y.f)
// but I'm allowed to pretend they have the _same_ X and bind that (nonexistent) type to a name (a)!
}
@main def main(): Unit = println(ohno.next)
This case gives a ClassCastException
at runtime, since the bad pattern is not stopped at compile-time.