@@ -10,11 +10,20 @@ import NameOps._
1010import Annotations .Annotation
1111import typer .ProtoTypes .constrained
1212import ast .untpd
13- import ast .DesugarEnums .SingletonCase
1413import ValueClasses .isDerivedValueClass
1514import SymUtils ._
15+ import util .Property
1616import config .Printers .derive
1717
18+ object SyntheticMembers {
19+
20+ /** Attachment marking an anonymous class as a singleton case that will extend from Mirror.Singleton. */
21+ val ExtendsSingletonMirror : Property .StickyKey [Unit ] = new Property .StickyKey
22+
23+ /** Attachment marking an anonymous class as a sum mirror that will extends from Mirror.Sum. */
24+ val ExtendsSumMirror : Property .StickyKey [Unit ] = new Property .StickyKey
25+ }
26+
1827/** Synthetic method implementations for case classes, case objects,
1928 * and value classes.
2029 *
@@ -38,6 +47,7 @@ import config.Printers.derive
3847 * def hashCode(): Int
3948 */
4049class SyntheticMembers (thisPhase : DenotTransformer ) {
50+ import SyntheticMembers ._
4151 import ast .tpd ._
4252
4353 private [this ] var myValueSymbols : List [Symbol ] = Nil
@@ -381,7 +391,6 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
381391 */
382392 def addMirrorSupport (impl : Template )(implicit ctx : Context ): Template = {
383393 val clazz = ctx.owner.asClass
384- val linked = clazz.linkedClass
385394
386395 var newBody = impl.body
387396 var newParents = impl.parents
@@ -392,40 +401,56 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
392401 classParents = oldClassInfo.classParents :+ parent)
393402 clazz.copySymDenotation(info = newClassInfo).installAfter(thisPhase)
394403 }
395- def addMethod (name : TermName , info : Type , body : (Symbol , Tree , Context ) => Tree ): Unit = {
404+ def addMethod (name : TermName , info : Type , cls : Symbol , body : (Symbol , Tree , Context ) => Tree ): Unit = {
396405 val meth = ctx.newSymbol(clazz, name, Synthetic | Method , info, coord = clazz.coord)
397406 if (! existingDef(meth, clazz).exists) {
398407 meth.entered
399408 newBody = newBody :+
400- synthesizeDef(meth, vrefss => ctx => body(linked , vrefss.head.head, ctx))
409+ synthesizeDef(meth, vrefss => ctx => body(cls , vrefss.head.head, ctx))
401410 }
402411 }
412+ val linked = clazz.linkedClass
403413 lazy val monoType = {
404- val monoType =
405- ctx.newSymbol(clazz, tpnme.MonoType , Synthetic , TypeAlias (linked.rawTypeRef), coord = clazz.coord)
406- existingDef(monoType, clazz).orElse {
414+ val existing = clazz.info.member(tpnme.MonoType ).symbol
415+ if (existing.exists && ! existing.is(Deferred )) existing
416+ else {
417+ val monoType =
418+ ctx.newSymbol(clazz, tpnme.MonoType , Synthetic , TypeAlias (linked.rawTypeRef), coord = clazz.coord)
407419 newBody = newBody :+ TypeDef (monoType).withSpan(ctx.owner.span.focus)
408420 monoType.entered
409421 }
410422 }
423+ def makeSingletonMirror () =
424+ addParent(defn.Mirror_SingletonType )
425+ def makeProductMirror () = {
426+ addParent(defn.Mirror_ProductType )
427+ addMethod(
428+ nme.fromProduct,
429+ MethodType (defn.ProductType :: Nil , monoType.typeRef),
430+ linked,
431+ fromProductBody(_, _)(_).ensureConforms(monoType.typeRef)) // t4758.scala or i3381.scala are examples where a cast is needed
432+ }
433+ def makeSumMirror (cls : Symbol ) = {
434+ addParent(defn.Mirror_SumType )
435+ addMethod(
436+ nme.ordinal,
437+ MethodType (monoType.typeRef :: Nil , defn.IntType ),
438+ cls,
439+ ordinalBody(_, _)(_))
440+ }
441+
411442 if (clazz.is(Module )) {
412- if (clazz.is(Case ))
413- addParent(defn.Mirror_SingletonType )
414- else if (linked.isGenericProduct) {
415- addParent(defn.Mirror_ProductType )
416- addMethod(nme.fromProduct, MethodType (defn.ProductType :: Nil , monoType.typeRef),
417- fromProductBody(_, _)(_).ensureConforms(monoType.typeRef)) // t4758.scala or i3381.scala are examples where a cast is needed
418- }
419- else if (linked.isGenericSum) {
420- addParent(defn.Mirror_SumType )
421- addMethod(nme.ordinal, MethodType (monoType.typeRef :: Nil , defn.IntType ),
422- ordinalBody(_, _)(_))
423- }
443+ if (clazz.is(Case )) makeSingletonMirror()
444+ else if (linked.isGenericProduct) makeProductMirror()
445+ else if (linked.isGenericSum) makeSumMirror(linked)
424446 else if (linked.is(Sealed ))
425447 derive.println(i " $linked is not a sum because ${linked.whyNotGenericSum}" )
426448 }
427- else if (impl.removeAttachment(SingletonCase ).isDefined)
428- addParent(defn.Mirror_SingletonType )
449+ else if (impl.removeAttachment(ExtendsSingletonMirror ).isDefined)
450+ makeSingletonMirror()
451+ else if (impl.removeAttachment(ExtendsSumMirror ).isDefined)
452+ makeSumMirror(monoType.typeRef.dealias.classSymbol)
453+
429454 cpy.Template (impl)(parents = newParents, body = newBody)
430455 }
431456
0 commit comments