Description
The fact that IsInstanceOfEvaluator
is a separate phase is nice for modularity but unfortunately it means that even though this works:
class Term[A]
case class Number(val n: Int) extends Term[Int]
object Test {
def f[B](t: Term[B]): B = t match {
case y @ Number(_) => y.n
}
}
this doesn't (example from SLS 8.3):
class Term[A]
class Number(val n: Int) extends Term[Int]
object Test {
def f[B](t: Term[B]): B = t match {
case y: Number => y.n
}
}
The first example typechecks because we explicitly check if the scrutinee is compatible with the pattern type : https://github.com/lampepfl/dotty/blob/04b0e85c70de36fd7b5a4b3ffd1b8add0963303d/src/dotty/tools/dotc/typer/Applications.scala#L758, this check is done with GADTflexible
set which allows B
to be constrained to be equal to Int
inside the case, if this is not done the method will not typecheck, but for patterns of the form x: T
, this check is not done in typer but in IsInstanceOfEvaluator
which is too late.
The optimizations can still be done in a separate phase but the checks need to be done in typer.