E184: Match Type No Cases — match type에 매칭되는 case 없음

E184: Match Type No Cases — match type에 매칭되는 case 없음

match type 축약(reduction)이 실패해서 스크루티니가 match type에 정의된 어떤 case에도 매칭되지 않을 때 발생할 수 있는 에러예요.

출처: Scala 3 Reference

본문

주의: 이 에러 코드는 컴파일러에 존재하지만 현재는 실제로 방출되지 않아요. match type 축약 실패에 대한 정보는 대신 암시적 해석이 실패할 때 다른 에러 메시지(예: E172 MissingImplicitArgument)의 일부로 포함돼요.

예시 (Example)

object Record {
  opaque type Rec[A <: Tuple] = Map[String, Any]
  object Rec {
    type HasKey[A <: Tuple, K] =
      A match
        case (K, t) *: _ => t
        case _ *: t => HasKey[t, K]

    val empty: Rec[EmptyTuple] = Map.empty

    extension [A <: Tuple](toMap: Rec[A])
      def fetch[K <: String & Singleton](key: K): HasKey[A, K] =
        toMap(key).asInstanceOf[HasKey[A, K]]
  }
}

def example =
  val foo: Any = Record.Rec.empty.fetch("foo")

에러 (Error)

이 에러 코드가 최종적으로 활성화되면 다음과 같은 메시지를 만들 거예요:

-- [E184] Type Error: example.scala:18:39 -------
18 |  val foo: Any = Record.Rec.empty.fetch("foo")
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |              Match type reduction failed since selector EmptyTuple.type
   |              matches none of the cases
   |
   |                  case (("foo" : String), t) *: _ => t
   |                  case _ *: t => Record.Rec.HasKey[t, ("foo" : String)]

해결 방법 (Solution)

match type에 빠진 case를 추가해주세요:

object Record {
  opaque type Rec[A <: Tuple] = Map[String, Any]
  object Rec {
    type HasKey[A <: Tuple, K] =
      A match
        case (K, t) *: _ => t
        case _ *: t => HasKey[t, K]
        case EmptyTuple => Nothing // additional case to satisfy missing case

    val empty: Rec[EmptyTuple] = Map.empty

    extension [A <: Tuple](toMap: Rec[A])
      def fetch[K <: String & Singleton](key: K): HasKey[A, K] =
        toMap(key).asInstanceOf[HasKey[A, K]]
  }
}

def example =
  val foo: Any = Record.Rec.empty.fetch("foo")

더 알아보기

match type을 정의할 때 스크루티니가 매칭될 수 있는 모든 case를 빠짐없이 다뤄야 해요. EmptyTuple 같은 추가 case가 필요할 수 있어요.