@@ -29,7 +29,7 @@ import Inferencing.fullyDefinedType
29
29
import Trees ._
30
30
import transform .SymUtils ._
31
31
import transform .TypeUtils ._
32
- import transform .SyntheticMembers .ExtendsSumMirror
32
+ import transform .SyntheticMembers ._
33
33
import Hashable ._
34
34
import util .{Property , SourceFile , NoSource }
35
35
import config .Config
@@ -859,35 +859,69 @@ trait Implicits { self: Typer =>
859
859
EmptyTree
860
860
}
861
861
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
+
862
877
lazy val synthesizedProductMirror : SpecialHandler =
863
878
(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 _ =>
866
883
if (monoType.termSymbol.is(CaseVal )) {
867
884
val modul = monoType.termSymbol
868
885
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
+ }
873
901
}
874
902
else if (monoType.classSymbol.isGenericProduct) {
875
903
val cls = monoType.classSymbol
876
904
val accessors = cls.caseAccessors.filterNot(_.is(PrivateLocal ))
877
- val elemTypes = accessors.map(monoType.memberInfo(_))
905
+ val elemTypes = accessors.map(monoType.memberInfo(_).widenExpr )
878
906
val label = ConstantType (Constant (cls.name.toString))
879
907
val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
880
908
val mirrorType =
881
909
defn.Mirror_ProductType
882
- .refinedWith(tpnme.MonoType , monoAlias )
910
+ .refinedWith(tpnme.MonoType , TypeAlias (monoType) )
883
911
.refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
884
912
.refinedWith(tpnme.Label , TypeAlias (label))
885
913
.refinedWith(tpnme.ElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
886
914
val modul = cls.linkedClass.sourceModule
887
915
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)
889
920
}
890
921
else EmptyTree
922
+ }
923
+ formal.member(tpnme.MonoType ).info match {
924
+ case monoAlias @ TypeAlias (monoType) => mirrorFor(monoType)
891
925
case _ => EmptyTree
892
926
}
893
927
}
@@ -907,9 +941,8 @@ trait Implicits { self: Typer =>
907
941
case info : PolyType =>
908
942
def instantiate (implicit ctx : Context ) = {
909
943
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
913
946
val tparams = poly.paramRefs
914
947
val variances = caseClass.typeParams.map(_.paramVariance)
915
948
val instanceTypes = (tparams, variances).zipped.map((tparam, variance) =>
@@ -929,20 +962,8 @@ trait Implicits { self: Typer =>
929
962
.refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
930
963
var modul = cls.linkedClass.sourceModule
931
964
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)
946
967
mirrorRef.cast(mirrorType)
947
968
case _ =>
948
969
EmptyTree
0 commit comments