@@ -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
@@ -815,35 +815,69 @@ trait Implicits { self: Typer =>
815
815
EmptyTree
816
816
}
817
817
818
+ /** Create an anonymous class `new Object { type MonoType = ... }`
819
+ * and mark it with given attachment so that it is made into a mirror at PostTyper.
820
+ */
821
+ def anonymousMirror (monoType : Type , attachment : Property .StickyKey [Unit ], span : Span )(implicit ctx : Context ) = {
822
+ val monoTypeDef = untpd.TypeDef (tpnme.MonoType , untpd.TypeTree (monoType))
823
+ val newImpl = untpd.Template (
824
+ constr = untpd.emptyConstructor,
825
+ parents = untpd.TypeTree (defn.ObjectType ) :: Nil ,
826
+ derived = Nil ,
827
+ self = EmptyValDef ,
828
+ body = monoTypeDef :: Nil
829
+ ).withAttachment(attachment, ())
830
+ typed(untpd.New (newImpl).withSpan(span))
831
+ }
832
+
818
833
lazy val synthesizedProductMirror : SpecialHandler =
819
834
(formal : Type , span : Span ) => implicit (ctx : Context ) => {
820
- formal.member(tpnme.MonoType ).info match {
821
- case monoAlias @ TypeAlias (monoType) =>
835
+ def mirrorFor (monoType : Type ): Tree = monoType match {
836
+ case AndType (tp1, tp2) =>
837
+ mirrorFor(tp1).orElse(mirrorFor(tp2))
838
+ case _ =>
822
839
if (monoType.termSymbol.is(CaseVal )) {
823
840
val modul = monoType.termSymbol
824
841
val label = ConstantType (Constant (modul.name.toString))
825
- val mirrorType = defn.Mirror_SingletonType
826
- .refinedWith(tpnme.MonoType , monoAlias)
827
- .refinedWith(tpnme.Label , TypeAlias (label))
828
- ref(modul).withSpan(span).cast(mirrorType)
842
+ if (modul.info.classSymbol.is(Scala2x )) {
843
+ val mirrorType =
844
+ defn.Mirror_SingletonProxyType
845
+ .refinedWith(tpnme.MonoType , TypeAlias (monoType))
846
+ .refinedWith(tpnme.Label , TypeAlias (label))
847
+ val mirrorRef = New (defn.Mirror_SingletonProxyType , ref(modul).withSpan(span) :: Nil )
848
+ mirrorRef.cast(mirrorType)
849
+ }
850
+ else {
851
+ val mirrorType = defn.Mirror_SingletonType
852
+ .refinedWith(tpnme.MonoType , TypeAlias (monoType))
853
+ .refinedWith(tpnme.Label , TypeAlias (label))
854
+ val mirrorRef = ref(modul).withSpan(span)
855
+ mirrorRef.cast(mirrorType)
856
+ }
829
857
}
830
858
else if (monoType.classSymbol.isGenericProduct) {
831
859
val cls = monoType.classSymbol
832
860
val accessors = cls.caseAccessors.filterNot(_.is(PrivateLocal ))
833
- val elemTypes = accessors.map(monoType.memberInfo(_))
861
+ val elemTypes = accessors.map(monoType.memberInfo(_).widenExpr )
834
862
val label = ConstantType (Constant (cls.name.toString))
835
863
val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
836
864
val mirrorType =
837
865
defn.Mirror_ProductType
838
- .refinedWith(tpnme.MonoType , monoAlias )
866
+ .refinedWith(tpnme.MonoType , TypeAlias (monoType) )
839
867
.refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
840
868
.refinedWith(tpnme.Label , TypeAlias (label))
841
869
.refinedWith(tpnme.ElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
842
870
val modul = cls.linkedClass.sourceModule
843
871
assert(modul.is(Module ))
844
- ref(modul).withSpan(span).cast(mirrorType)
872
+ val mirrorRef =
873
+ if (cls.is(Scala2x )) anonymousMirror(monoType, ExtendsProductMirror , span)
874
+ else ref(modul).withSpan(span)
875
+ mirrorRef.cast(mirrorType)
845
876
}
846
877
else EmptyTree
878
+ }
879
+ formal.member(tpnme.MonoType ).info match {
880
+ case monoAlias @ TypeAlias (monoType) => mirrorFor(monoType)
847
881
case _ => EmptyTree
848
882
}
849
883
}
@@ -863,9 +897,8 @@ trait Implicits { self: Typer =>
863
897
case info : PolyType =>
864
898
def instantiate (implicit ctx : Context ) = {
865
899
val poly = constrained(info, untpd.EmptyTree )._1
866
- val mono @ MethodType (_) = poly.resultType
867
- val resType = mono.finalResultType
868
- resType <:< cls.appliedRef
900
+ val resType = poly.finalResultType
901
+ resType <:< monoType
869
902
val tparams = poly.paramRefs
870
903
val variances = caseClass.typeParams.map(_.paramVariance)
871
904
val instanceTypes = (tparams, variances).zipped.map((tparam, variance) =>
@@ -885,20 +918,8 @@ trait Implicits { self: Typer =>
885
918
.refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
886
919
var modul = cls.linkedClass.sourceModule
887
920
val mirrorRef =
888
- if (modul.exists) ref(modul).withSpan(span)
889
- else {
890
- // create an anonymous class `new Object { type MonoType = ... }`
891
- // and mark it so that it is made into a `Mirror.Sum` at PostTyper.
892
- val monoTypeDef = untpd.TypeDef (tpnme.MonoType , untpd.TypeTree (monoType))
893
- val newImpl = untpd.Template (
894
- constr = untpd.emptyConstructor,
895
- parents = untpd.TypeTree (defn.ObjectType ) :: Nil ,
896
- derived = Nil ,
897
- self = EmptyValDef ,
898
- body = monoTypeDef :: Nil
899
- ).withAttachment(ExtendsSumMirror , ())
900
- typed(untpd.New (newImpl).withSpan(span))
901
- }
921
+ if (modul.exists && ! cls.is(Scala2x )) ref(modul).withSpan(span)
922
+ else anonymousMirror(monoType, ExtendsSumMirror , span)
902
923
mirrorRef.cast(mirrorType)
903
924
case _ =>
904
925
EmptyTree
0 commit comments