Scala:路径相关类型的模式匹配

Scala: pattern matching on a path-dependent type

无法弄清楚为什么 Scala 2.13 对这里的模式匹配不满意

  trait A {
    sealed trait T
    case class TImpl() extends T
  }

  trait Fail[B <: A] {
    val a: B // no error if `a: A`
    def foo(t : a.T): Unit = t match {
      case _: a.TImpl => // "match may not be exhaustive. It would fail on the following input: TImpl()"
    }
  }

任何合理的解决方法? Dotty

似乎没问题

如果你想知道为什么原则上模式匹配不能穷举,例如看下面的例子

trait A {
  sealed trait T
  case class TImpl() extends T
}

trait Fail[B <: A] {
  val a: B
  def foo(t : a.T): Unit = t match {
    case _: a.TImpl => 
  }
}

class B extends A
val b = new B
class FailImpl extends Fail[b.type] {
  override val a: b.type = b
}
val fail: Fail[b.type] = new FailImpl

class C
case class CImpl() extends C with b.T
val x = CImpl()
fail.foo(x) // MatchError

可以说其实我们没有C。好吧,编译器应该足够聪明,可以弄清楚这一点。

如果你想关闭警告你可以写@unchecked

def foo(t : a.T): Unit = (t: @unchecked) match {
  case _: a.TImpl => 
}

根据规范,

If the selector of a pattern match is an instance of a sealed class, the compilation of pattern matching can emit warnings which diagnose that a given set of patterns is not exhaustive, i.e. that there is a possibility of a MatchError being raised at run-time.

https://scala-lang.org/files/archive/spec/2.13/08-pattern-matching.html#pattern-matching-expressions

编译器可以发出警告但必须。因此,没有警告并不能保证模式匹配是详尽无遗的。