Back to Scala3

E184: Match Type No Cases

docs/_docs/reference/error-codes/E184.md

3.8.42.3 KB
Original Source

E184: Match Type No Cases

This error would be emitted when a match type reduction fails because the scrutinee matches none of the cases defined in the match type.

Note: This error code exists in the compiler but is currently not emitted. The information about failed match type reduction is instead included as part of other error messages (like E172 MissingImplicitArgument) when implicit resolution fails.


Example

scala
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

When this error code is eventually enabled, it would produce:

scala
-- [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

Ensure the match types includes additional missing case:

scala
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")
<!-- SOURCE-ONLY: Remove the notice below once this page has been manually updated. --> <aside class="warning"> This reference page was created with LLM assistance - the description of the error code may not be accurate or cover all possible scenarios. </aside>