1

Considering the following example:

object MatchDuckType {

  trait Sup
  class Sub1() extends Sup {
    def v1: String = "a"
  }

  def example(v: Any) = {

    v match {

      case _: Sup { def v1: String } => println(1)
      case _ => println(2)
    }
  }

  def main(args: Array[String]): Unit = {
    example(Sub1())
    example(1)
  }
}

The compiler gave the following error:

MatchDuckType.scala:16:12: the type test for xxx.MatchDuckType.Sup{v1: String} cannot be checked at runtime

This statement is clearly wrong, as Sup { def v1: String } can be easily checked by Java runtime reflection (by first getting the class of the term, then getting its method signatures). Why does the warning still exist? Is it a bug in compiler?

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
tribbloid
  • 4,026
  • 14
  • 64
  • 103
  • I feel like Scala 3 need a more systematic approach to pattern matching, the easiest way to do so is probably by explaining its equivalent desugared form as part of the warning message – tribbloid Feb 13 '23 at 20:49
  • You can switch on `-Xprint:typer` or `-Xprint:jvm` in Scala 2 or `-Xprint:typer` or `-Xprint:genBCode` in Scala 3 – Dmytro Mitin Feb 14 '23 at 06:52

1 Answers1

4

That this doesn't work isn't merely a "bug"; including such a thing in the language would require substantial design, specification, and implementation work.

The feature you were hoping for doesn't exist in either Scala 2 or Scala 3.

I found a feature request for this dating back to 2007 (!), but it never attracted much attention: https://github.com/scala/bug/issues/329

Even if the feature did exist, the feature would be platform-specific and limited in scope: it would only work on the JVM, not on JS or Native, and it would only work for the subset of refinement types that can be faithfully be represented in bytecode. That leaves out a lot of the Scala type system.

(At least without TypeTag, but TypeTag is Scala 2-only; the feature request on TypeTag-based matching is https://github.com/scala/bug/issues/6517 . In a Scala 3 context, consider trying to use match types instead?)

As for your remark about desugaring, pattern matches desugar to isInstanceOf, and the behavior of isInstanceOf is the same, so this isn't really about pattern matching per se, it's about type tests.

Seth Tisue
  • 29,985
  • 11
  • 82
  • 149
  • 1
    Good point, after introduction of JS or Native, the reflection becomes more of a mine field that can't be relied upon. I like the idea of adjoint Typeable/TypeTag in bytecode. I just don't like to summon their definition in code manually :) Since type erasure happens in so many languages. It would be interesting to see research in "gradual/on-demand" runtime inhabitance check – tribbloid Feb 14 '23 at 21:51