Skip to content

Move instanceof checks in typer to allow typing more GADTs #1307

Closed
@smarter

Description

@smarter

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions