Skip to content

Commit c031b30

Browse files
oderskymilessabin
authored andcommitted
Make enum cases implement Mirror.Singleton
At the same time, don't make Mirror.Singleton a scala.Product.
1 parent 4cccf41 commit c031b30

File tree

3 files changed

+37
-30
lines changed

3 files changed

+37
-30
lines changed

compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,13 @@ object DesugarEnums {
115115
val toStringDef =
116116
DefDef(nme.toString_, Nil, Nil, TypeTree(), Ident(nme.name))
117117
.withFlags(Override)
118-
def creator = New(Template(emptyConstructor, enumClassRef :: Nil, Nil, EmptyValDef,
119-
List(enumTagDef, toStringDef) ++ registerCall))
118+
def creator = New(Template(
119+
constr = emptyConstructor,
120+
parents = enumClassRef :: TypeTree(defn.Mirror_SingletonType) :: Nil,
121+
derived = Nil,
122+
self = EmptyValDef,
123+
body = List(enumTagDef, toStringDef) ++ registerCall
124+
))
120125
DefDef(nme.DOLLAR_NEW, Nil,
121126
List(List(param(nme.tag, defn.IntType), param(nme.name, defn.StringType))),
122127
TypeTree(), creator)
@@ -258,7 +263,9 @@ object DesugarEnums {
258263
DefDef(nme.toString_, Nil, Nil, TypeTree(defn.StringType), Literal(Constant(name.toString)))
259264
.withFlags(Override)
260265
val (tagMeth, scaffolding) = enumTagMeth(CaseKind.Object)
261-
val impl1 = cpy.Template(impl)(body = List(tagMeth, toStringMeth) ++ registerCall)
266+
val impl1 = cpy.Template(impl)(
267+
parents = impl.parents :+ TypeTree(defn.Mirror_SingletonType),
268+
body = List(tagMeth, toStringMeth) ++ registerCall)
262269
val vdef = ValDef(name, TypeTree(), New(impl1)).withMods(mods | Final)
263270
flatTree(scaffolding ::: vdef :: Nil).withSpan(span)
264271
}

library/src/scala/deriving.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,18 @@ object deriving {
3737
def fromProduct(p: scala.Product): MonoType
3838
}
3939

40-
trait Singleton extends Product with scala.Product {
40+
trait Singleton extends Product {
4141
type MonoType = this.type
4242
def fromProduct(p: scala.Product) = this
4343

4444
def productElement(n: Int): Any = throw new IndexOutOfBoundsException(n.toString)
4545
def productArity: Int = 0
4646
}
47-
}
4847

49-
type MirrorOf[T] = Mirror { type MonoType = T }
50-
type ProductMirrorOf[T] = Mirror.Product { type MonoType = T }
51-
type SumMirrorOf[T] = Mirror.Sum { type MonoType = T }
48+
type Of[T] = Mirror { type MonoType = T }
49+
type ProductOf[T] = Mirror.Product { type MonoType = T }
50+
type SumOf[T] = Mirror.Sum { type MonoType = T }
51+
}
5252

5353
/** Helper class to turn arrays into products */
5454
class ArrayProduct(val elems: Array[AnyRef]) extends Product {

tests/run/typeclass-derivation2d.scala

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ object Deriving {
1616
/** The mirrored *-type */
1717
type _MonoType
1818
}
19-
type MirrorOf[T] = Mirror { type _MonoType = T }
20-
type ProductMirrorOf[T] = Mirror.Product { type _MonoType = T }
21-
type SumMirrorOf[T] = Mirror.Sum { type _MonoType = T }
2219

2320
object Mirror {
2421

@@ -51,7 +48,10 @@ object Deriving {
5148
type _MonoType = this.type
5249
def _fromProduct(p: scala.Product) = this
5350
}
54-
}
51+
type Of[T] = Mirror { type _MonoType = T }
52+
type ProductOf[T] = Mirror.Product { type _MonoType = T }
53+
type SumOf[T] = Mirror.Sum { type _MonoType = T }
54+
}
5555

5656
/** Helper class to turn arrays into products */
5757
class ArrayProduct(val elems: Array[AnyRef]) extends Product {
@@ -212,28 +212,28 @@ object Eq {
212212
true
213213
}
214214

215-
inline def eqlProduct[T](m: ProductMirrorOf[T])(x: Any, y: Any): Boolean =
215+
inline def eqlProduct[T](m: Mirror.ProductOf[T])(x: Any, y: Any): Boolean =
216216
eqlElems[m.ElemTypes](0)(x, y)
217217

218218
inline def eqlCases[Alts](n: Int)(x: Any, y: Any, ord: Int): Boolean =
219219
inline erasedValue[Alts] match {
220220
case _: (alt *: alts1) =>
221221
if (ord == n)
222222
implicit match {
223-
case m: ProductMirrorOf[`alt`] => eqlElems[m.ElemTypes](0)(x, y)
223+
case m: Mirror.ProductOf[`alt`] => eqlElems[m.ElemTypes](0)(x, y)
224224
}
225225
else eqlCases[alts1](n + 1)(x, y, ord)
226226
case _: Unit =>
227227
false
228228
}
229229

230-
inline def derived[T](implicit ev: MirrorOf[T]): Eq[T] = new Eq[T] {
230+
inline def derived[T](implicit ev: Mirror.Of[T]): Eq[T] = new Eq[T] {
231231
def eql(x: T, y: T): Boolean =
232232
inline ev match {
233-
case m: SumMirrorOf[T] =>
233+
case m: Mirror.SumOf[T] =>
234234
val ord = m.ordinal(x)
235235
ord == m.ordinal(y) && eqlCases[m.ElemTypes](0)(x, y, ord)
236-
case m: ProductMirrorOf[T] =>
236+
case m: Mirror.ProductOf[T] =>
237237
eqlElems[m.ElemTypes](0)(x, y)
238238
}
239239
}
@@ -272,7 +272,7 @@ object Pickler {
272272
case _: (alt *: alts1) =>
273273
if (ord == n)
274274
implicit match {
275-
case m: ProductMirrorOf[`alt`] => pickleElems[m.ElemTypes](0)(buf, x)
275+
case m: Mirror.ProductOf[`alt`] => pickleElems[m.ElemTypes](0)(buf, x)
276276
}
277277
else pickleCases[alts1](n + 1)(buf, x, ord)
278278
case _: Unit =>
@@ -290,7 +290,7 @@ object Pickler {
290290
case _: Unit =>
291291
}
292292

293-
inline def unpickleCase[T, Elems <: Tuple](buf: mutable.ListBuffer[Int], m: ProductMirrorOf[T]): T = {
293+
inline def unpickleCase[T, Elems <: Tuple](buf: mutable.ListBuffer[Int], m: Mirror.ProductOf[T]): T = {
294294
inline val size = constValue[Tuple.Size[Elems]]
295295
inline if (size == 0)
296296
m._fromProduct(EmptyProduct)
@@ -306,30 +306,30 @@ object Pickler {
306306
case _: (alt *: alts1) =>
307307
if (ord == n)
308308
implicit match {
309-
case m: ProductMirrorOf[`alt` & T] =>
309+
case m: Mirror.ProductOf[`alt` & T] =>
310310
unpickleCase[`alt` & T, m.ElemTypes](buf, m)
311311
}
312312
else unpickleCases[T, alts1](n + 1)(buf, ord)
313313
case _: Unit =>
314314
throw new IndexOutOfBoundsException(s"unexpected ordinal number: $ord")
315315
}
316316

317-
inline def derived[T](implicit ev: MirrorOf[T]): Pickler[T] = new {
317+
inline def derived[T](implicit ev: Mirror.Of[T]): Pickler[T] = new {
318318
def pickle(buf: mutable.ListBuffer[Int], x: T): Unit =
319319
inline ev match {
320-
case m: SumMirrorOf[T] =>
320+
case m: Mirror.SumOf[T] =>
321321
val ord = m.ordinal(x)
322322
buf += ord
323323
pickleCases[m.ElemTypes](0)(buf, x, ord)
324-
case m: ProductMirrorOf[T] =>
324+
case m: Mirror.ProductOf[T] =>
325325
pickleElems[m.ElemTypes](0)(buf, x)
326326
}
327327
def unpickle(buf: mutable.ListBuffer[Int]): T =
328328
inline ev match {
329-
case m: SumMirrorOf[T] =>
329+
case m: Mirror.SumOf[T] =>
330330
val ord = nextInt(buf)
331331
unpickleCases[T, m.ElemTypes](0)(buf, ord)
332-
case m: ProductMirrorOf[T] =>
332+
case m: Mirror.ProductOf[T] =>
333333
unpickleCase[T, m.ElemTypes](buf, m)
334334
}
335335
}
@@ -365,7 +365,7 @@ object Show {
365365
Nil
366366
}
367367

368-
inline def showCase(x: Any, m: ProductMirrorOf[_]): String = {
368+
inline def showCase(x: Any, m: Mirror.ProductOf[_]): String = {
369369
val label = constValue[m.CaseLabel]
370370
inline m match {
371371
case m: Mirror.Singleton => label
@@ -378,21 +378,21 @@ object Show {
378378
case _: (alt *: alts1) =>
379379
if (ord == n)
380380
implicit match {
381-
case m: ProductMirrorOf[`alt`] =>
381+
case m: Mirror.ProductOf[`alt`] =>
382382
showCase(x, m)
383383
}
384384
else showCases[alts1](n + 1)(x, ord)
385385
case _: Unit =>
386386
throw new MatchError(x)
387387
}
388388

389-
inline def derived[T](implicit ev: MirrorOf[T]): Show[T] = new {
389+
inline def derived[T](implicit ev: Mirror.Of[T]): Show[T] = new {
390390
def show(x: T): String =
391391
inline ev match {
392-
case m: SumMirrorOf[T] =>
392+
case m: Mirror.SumOf[T] =>
393393
val ord = m.ordinal(x)
394394
showCases[m.ElemTypes](0)(x, ord)
395-
case m: ProductMirrorOf[T] =>
395+
case m: Mirror.ProductOf[T] =>
396396
showCase(x, m)
397397
}
398398
}

0 commit comments

Comments
 (0)