diff --git a/docs/docs/reference/contextual/derivation.md b/docs/docs/reference/contextual/derivation.md index a446500c1037..ffbb5ab6de0d 100644 --- a/docs/docs/reference/contextual/derivation.md +++ b/docs/docs/reference/contextual/derivation.md @@ -129,6 +129,10 @@ Note the following properties of `Mirror` types, Scala 2 versions of shapeless). Instead the collection of child types of a data type is represented by an ordinary, possibly parameterized, tuple type. Dotty's metaprogramming facilities can be used to work with these tuple types as-is, and higher level libraries can be built on top of them. ++ For both product and sum types, the elements of `MirroredElemTypes` are arranged in definition order (i.e. `Branch[T]` + precedes `Leaf[T]` in `MirroredElemTypes` for `Tree` because `Branch` is defined before `Leaf` in the source file). + This means that `Mirror.Sum` differs in this respect from shapeless's generic representation for ADTs in Scala 2, + where the constructors are ordered alphabetically by name. + The methods `ordinal` and `fromProduct` are defined in terms of `MirroredMonoType` which is the type of kind-`*` which is obtained from `MirroredType` by wildcarding its type parameters. diff --git a/tests/run/deriving-constructor-order.scala b/tests/run/deriving-constructor-order.scala new file mode 100644 index 000000000000..89c580971fda --- /dev/null +++ b/tests/run/deriving-constructor-order.scala @@ -0,0 +1,24 @@ +import scala.compiletime.erasedValue +import scala.deriving.Mirror + +object Test extends App { + inline def checkElems[A, T](using inline A: Mirror.SumOf[A]): Unit = + inline erasedValue[A.MirroredElemTypes] match { + case _: T => () + } + + sealed trait Base1 + case class Foo() extends Base1 + case object Bar extends Base1 + case class Qux(i: Int) extends Base1 + + checkElems[Base1, (Foo, Bar.type, Qux)] + + enum Tree[+T] { + case Empty + case Branch[T](left: Tree[T], right: Tree[T]) extends Tree[T] + case Leaf[T](elem: T) extends Tree[T] + } + + checkElems[Tree[String], (Tree.Empty.type, Tree.Branch[String], Tree.Leaf[String])] +}