Skip to content

In Scala 3.8.0 Mirror.SumOf changed labels ordinals for Option Some/None #25003

@rmgk

Description

@rmgk

Compiler version

3.8.0

Minimized example

The order and name of the Mirror labels changed in Scala 3.8, which also causes the Mirror.ordinal method to return different values. In short:

// for 3.7.4
type MirroredElemLabels = ("None$", "Some")
// for 3.8.0
type MirroredElemLabels = ("Some", "None")

Full interaction:

❯ scala-cli repl -S 3.7
Welcome to Scala 3.7.4 (17.0.16, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
                                                                                                                                                   
scala> import scala.deriving.Mirror
     | 
     | val mirror = summon[Mirror.SumOf[Option[Int]]]
     | mirror.ordinal(None)
     | mirror.ordinal(Some(1))
val mirror:
  scala.deriving.Mirror.Sum{
    type MirroredMonoType = Option[Int]; type MirroredType = Option[Int];
      type MirroredLabel = "Option";
      type MirroredElemTypes = (None.type, Some[Int]);
      type MirroredElemLabels = ("None$", "Some")
  } = anon$1@2fccf49e
val res0: Int = 0
val res1: Int = 1
                                                                                                                                                   
scala> 

~ took 6s 
❯ scala-cli repl -S 3.8
Welcome to Scala 3.8.0 (17.0.16, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
                                                                                                                                                   
scala> import scala.deriving.Mirror
       
       val mirror = summon[Mirror.SumOf[Option[Int]]]
       mirror.ordinal(None)
       mirror.ordinal(Some(1))
val mirror:
  scala.deriving.Mirror.Sum{
    type MirroredMonoType = Option[Int]; type MirroredType = Option[Int];
      type MirroredLabel = "Option";
      type MirroredElemTypes = (Some[Int], None.type);
      type MirroredElemLabels = ("Some", "None")
  } = anon$1@11e930e
val res0: Int = 1
val res1: Int = 0

Now, I am not sure if one is supposed to be able to rely on the ordering of classes between Scala versions (the Scaladoc only mentions enums), but it would be good to at least mention if this is not the case.

This one is somewhat easy to work around, but I do prefer the 3.7 ordinals, because there None < Some.

Metadata

Metadata

Assignees

No one assigned

    Labels

    stat:needs triageEvery issue needs to have an "area" and "itype" label

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions