@@ -29,7 +29,7 @@ import Inferencing.fullyDefinedType
2929import Trees ._
3030import transform .SymUtils ._
3131import transform .TypeUtils ._
32- import transform .SyntheticMembers .ExtendsSumMirror
32+ import transform .SyntheticMembers ._
3333import Hashable ._
3434import util .{Property , SourceFile , NoSource }
3535import config .Config
@@ -859,35 +859,69 @@ trait Implicits { self: Typer =>
859859 EmptyTree
860860 }
861861
862+ /** Create an anonymous class `new Object { type MonoType = ... }`
863+ * and mark it with given attachment so that it is made into a mirror at PostTyper.
864+ */
865+ def anonymousMirror (monoType : Type , attachment : Property .StickyKey [Unit ], span : Span )(implicit ctx : Context ) = {
866+ val monoTypeDef = untpd.TypeDef (tpnme.MonoType , untpd.TypeTree (monoType))
867+ val newImpl = untpd.Template (
868+ constr = untpd.emptyConstructor,
869+ parents = untpd.TypeTree (defn.ObjectType ) :: Nil ,
870+ derived = Nil ,
871+ self = EmptyValDef ,
872+ body = monoTypeDef :: Nil
873+ ).withAttachment(attachment, ())
874+ typed(untpd.New (newImpl).withSpan(span))
875+ }
876+
862877 lazy val synthesizedProductMirror : SpecialHandler =
863878 (formal : Type , span : Span ) => implicit (ctx : Context ) => {
864- formal.member(tpnme.MonoType ).info match {
865- case monoAlias @ TypeAlias (monoType) =>
879+ def mirrorFor (monoType : Type ): Tree = monoType match {
880+ case AndType (tp1, tp2) =>
881+ mirrorFor(tp1).orElse(mirrorFor(tp2))
882+ case _ =>
866883 if (monoType.termSymbol.is(CaseVal )) {
867884 val modul = monoType.termSymbol
868885 val label = ConstantType (Constant (modul.name.toString))
869- val mirrorType = defn.Mirror_SingletonType
870- .refinedWith(tpnme.MonoType , monoAlias)
871- .refinedWith(tpnme.Label , TypeAlias (label))
872- ref(modul).withSpan(span).cast(mirrorType)
886+ if (modul.info.classSymbol.is(Scala2x )) {
887+ val mirrorType =
888+ defn.Mirror_SingletonProxyType
889+ .refinedWith(tpnme.MonoType , TypeAlias (monoType))
890+ .refinedWith(tpnme.Label , TypeAlias (label))
891+ val mirrorRef = New (defn.Mirror_SingletonProxyType , ref(modul).withSpan(span) :: Nil )
892+ mirrorRef.cast(mirrorType)
893+ }
894+ else {
895+ val mirrorType = defn.Mirror_SingletonType
896+ .refinedWith(tpnme.MonoType , TypeAlias (monoType))
897+ .refinedWith(tpnme.Label , TypeAlias (label))
898+ val mirrorRef = ref(modul).withSpan(span)
899+ mirrorRef.cast(mirrorType)
900+ }
873901 }
874902 else if (monoType.classSymbol.isGenericProduct) {
875903 val cls = monoType.classSymbol
876904 val accessors = cls.caseAccessors.filterNot(_.is(PrivateLocal ))
877- val elemTypes = accessors.map(monoType.memberInfo(_))
905+ val elemTypes = accessors.map(monoType.memberInfo(_).widenExpr )
878906 val label = ConstantType (Constant (cls.name.toString))
879907 val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
880908 val mirrorType =
881909 defn.Mirror_ProductType
882- .refinedWith(tpnme.MonoType , monoAlias )
910+ .refinedWith(tpnme.MonoType , TypeAlias (monoType) )
883911 .refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
884912 .refinedWith(tpnme.Label , TypeAlias (label))
885913 .refinedWith(tpnme.ElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
886914 val modul = cls.linkedClass.sourceModule
887915 assert(modul.is(Module ))
888- ref(modul).withSpan(span).cast(mirrorType)
916+ val mirrorRef =
917+ if (cls.is(Scala2x )) anonymousMirror(monoType, ExtendsProductMirror , span)
918+ else ref(modul).withSpan(span)
919+ mirrorRef.cast(mirrorType)
889920 }
890921 else EmptyTree
922+ }
923+ formal.member(tpnme.MonoType ).info match {
924+ case monoAlias @ TypeAlias (monoType) => mirrorFor(monoType)
891925 case _ => EmptyTree
892926 }
893927 }
@@ -907,9 +941,8 @@ trait Implicits { self: Typer =>
907941 case info : PolyType =>
908942 def instantiate (implicit ctx : Context ) = {
909943 val poly = constrained(info, untpd.EmptyTree )._1
910- val mono @ MethodType (_) = poly.resultType
911- val resType = mono.finalResultType
912- resType <:< cls.appliedRef
944+ val resType = poly.finalResultType
945+ resType <:< monoType
913946 val tparams = poly.paramRefs
914947 val variances = caseClass.typeParams.map(_.paramVariance)
915948 val instanceTypes = (tparams, variances).zipped.map((tparam, variance) =>
@@ -929,20 +962,8 @@ trait Implicits { self: Typer =>
929962 .refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
930963 var modul = cls.linkedClass.sourceModule
931964 val mirrorRef =
932- if (modul.exists) ref(modul).withSpan(span)
933- else {
934- // create an anonymous class `new Object { type MonoType = ... }`
935- // and mark it so that it is made into a `Mirror.Sum` at PostTyper.
936- val monoTypeDef = untpd.TypeDef (tpnme.MonoType , untpd.TypeTree (monoType))
937- val newImpl = untpd.Template (
938- constr = untpd.emptyConstructor,
939- parents = untpd.TypeTree (defn.ObjectType ) :: Nil ,
940- derived = Nil ,
941- self = EmptyValDef ,
942- body = monoTypeDef :: Nil
943- ).withAttachment(ExtendsSumMirror , ())
944- typed(untpd.New (newImpl).withSpan(span))
945- }
965+ if (modul.exists && ! cls.is(Scala2x )) ref(modul).withSpan(span)
966+ else anonymousMirror(monoType, ExtendsSumMirror , span)
946967 mirrorRef.cast(mirrorType)
947968 case _ =>
948969 EmptyTree
0 commit comments