scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

Missing unchecked warning for type pattern, invariant extends contravariant #12439

Open lrytz opened 3 years ago

lrytz commented 3 years ago

From https://github.com/scala/scala/pull/9672#issuecomment-892850835

trait C[+T]
trait D[T] extends C[T] {
  def f(x: T): T
}
class E extends D[String] {
  def f(x: String) = x.trim
}

object Test {
  def foo[T](c: C[T], t: T): Any = c match {
    case d: D[T] => d.f(t)
    case _ => 0
  }
  def main(args: Array[String]): Unit = {
    foo[Any](new E, 1)
  }
}

Doesn't give an unchecked warning in Scala 2 (fixed in Scala 3) and runs into a CCE.

lrytz commented 3 years ago

The method in question is propagateKnownTypes (https://github.com/scala/scala/blob/2149b975b5f39d6c9d8ab8431477d1fa6b60edda/src/compiler/scala/tools/nsc/typechecker/Checkable.scala#L98).

Related to https://github.com/scala/bug/issues/6944. Also related to this comment: https://github.com/scala/scala/blob/2149b975b5f39d6c9d8ab8431477d1fa6b60edda/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala#L246-L248

In Scala 3 the implementation for the unchecked warning is reusing the pattern type inference (https://github.com/lampepfl/dotty/blob/38b983c1b4a61d4c45f314ae895b95317c322c62/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala#L101), which seems the right thing to do. I don't know gadt inference in Scala 2, but constrainPatternType seems potentially better grounded (https://github.com/lampepfl/dotty/pull/6398).

So the cost/benefit of fixing this "the right way" seems too high at least for me personally.