Scala 3 derivation: Why are MirroredElemTypes of Sum not <: NonEmptyTuple?

I was playing around with Scala 3 type class derivation and noticed the following:

As far as I can see, the compiler will only synthesize a Mirror.SumOf[T] if T has at least one concrete member.
I tried various things like empty enums, sealed traits without concrete members, … and the compiler always denies providing a Mirror.SumOf[x] for them with an error message saying “Failed to synthesize an instance of type deriving.Mirror.SumOf[xyz]: class xyz is not a generic sum because it does not have subclasses” (see Scastie - An interactive playground for Scala.).

Yet still, the type of Mirror.SumOf[T] is defined as:

type SumOf[T] = Mirror.Sum {
   /* other members omitted */ 
  type MirroredElemTypes <: Tuple
}

I was wondering why it is not type MirroredElemTypes <: NonEmptyTuple?

Implementing type class derivation would be a little bit less if one would not need to deal with the EmptyTuple case there.

Is there any case where MirroredElemTypes of a Sum could be empty?

1 Like

The compiler currently will refuse to generate a synthetic Sum Mirror for a sealed trait with no subclasses for example.

However nothing stops you from defining your own given Mirror for a sealed trait with no subclasses

Oh wow, thanks a lot, I had not thought about that!

What I actually wanted to do is define an own Mirror that guarantees (on the typelevel) that MirroredElemTypes is a NonEmptyTuple and that seems to work as well:

  type MySumOf[T] = Mirror.Sum {
    type MirroredType = T
    type MirroredMonoType = T
    type MirroredElemTypes <: NonEmptyTuple
  }

(It did not actually bring me much further in my quest do reduce .asInstanceOf-calls in my code, but it revealed what seems like a universe of new possibilites to me.)