@@ -862,7 +862,7 @@ trait Implicits { self: Typer =>
862
862
/** Create an anonymous class `new Object { type MonoType = ... }`
863
863
* and mark it with given attachment so that it is made into a mirror at PostTyper.
864
864
*/
865
- def anonymousMirror (monoType : Type , attachment : Property .StickyKey [Unit ], span : Span )(implicit ctx : Context ) = {
865
+ private def anonymousMirror (monoType : Type , attachment : Property .StickyKey [Unit ], span : Span )(implicit ctx : Context ) = {
866
866
val monoTypeDef = untpd.TypeDef (tpnme.MonoType , untpd.TypeTree (monoType))
867
867
val newImpl = untpd.Template (
868
868
constr = untpd.emptyConstructor,
@@ -874,6 +874,18 @@ trait Implicits { self: Typer =>
874
874
typed(untpd.New (newImpl).withSpan(span))
875
875
}
876
876
877
+ /** The mirror type
878
+ *
879
+ * <parent> { MonoType = <monoType; Label = <label> }
880
+ */
881
+ private def mirrorCore (parent : Type , monoType : Type , label : Name )(implicit ctx : Context ) =
882
+ parent
883
+ .refinedWith(tpnme.MonoType , TypeAlias (monoType))
884
+ .refinedWith(tpnme.Label , TypeAlias (ConstantType (Constant (label.toString))))
885
+
886
+ /** An implied instance for a type of the form `Mirror.Product { type MonoType = T }`
887
+ * where `T` is a generic product type or a case object or an enum case.
888
+ */
877
889
lazy val synthesizedProductMirror : SpecialHandler =
878
890
(formal : Type , span : Span ) => implicit (ctx : Context ) => {
879
891
def mirrorFor (monoType : Type ): Tree = monoType match {
@@ -882,19 +894,13 @@ trait Implicits { self: Typer =>
882
894
case _ =>
883
895
if (monoType.termSymbol.is(CaseVal )) {
884
896
val modul = monoType.termSymbol
885
- val label = ConstantType (Constant (modul.name.toString))
886
897
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))
898
+ val mirrorType = mirrorCore(defn.Mirror_SingletonProxyType , monoType, modul.name)
891
899
val mirrorRef = New (defn.Mirror_SingletonProxyType , ref(modul).withSpan(span) :: Nil )
892
900
mirrorRef.cast(mirrorType)
893
901
}
894
902
else {
895
- val mirrorType = defn.Mirror_SingletonType
896
- .refinedWith(tpnme.MonoType , TypeAlias (monoType))
897
- .refinedWith(tpnme.Label , TypeAlias (label))
903
+ val mirrorType = mirrorCore(defn.Mirror_SingletonType , monoType, modul.name)
898
904
val mirrorRef = ref(modul).withSpan(span)
899
905
mirrorRef.cast(mirrorType)
900
906
}
@@ -903,13 +909,10 @@ trait Implicits { self: Typer =>
903
909
val cls = monoType.classSymbol
904
910
val accessors = cls.caseAccessors.filterNot(_.is(PrivateLocal ))
905
911
val elemTypes = accessors.map(monoType.memberInfo(_).widenExpr)
906
- val label = ConstantType (Constant (cls.name.toString))
907
912
val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
908
913
val mirrorType =
909
- defn.Mirror_ProductType
910
- .refinedWith(tpnme.MonoType , TypeAlias (monoType))
914
+ mirrorCore(defn.Mirror_ProductType , monoType, cls.name)
911
915
.refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
912
- .refinedWith(tpnme.Label , TypeAlias (label))
913
916
.refinedWith(tpnme.ElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
914
917
val modul = cls.linkedClass.sourceModule
915
918
assert(modul.is(Module ))
@@ -926,19 +929,28 @@ trait Implicits { self: Typer =>
926
929
}
927
930
}
928
931
932
+ /** An implied instance for a type of the form `Mirror.Sum { type MonoType = T }`
933
+ * where `T` is a generic sum type.
934
+ */
929
935
lazy val synthesizedSumMirror : SpecialHandler =
930
936
(formal : Type , span : Span ) => implicit (ctx : Context ) =>
931
937
formal.member(tpnme.MonoType ).info match {
932
- case monoAlias @ TypeAlias (monoType) if monoType.classSymbol.isGenericSum =>
938
+ case TypeAlias (monoType) if monoType.classSymbol.isGenericSum =>
933
939
val cls = monoType.classSymbol
934
- val label = ConstantType (Constant (cls.name.toString))
935
940
val elemTypes = cls.children.map {
936
941
case caseClass : ClassSymbol =>
937
942
assert(caseClass.is(Case ))
938
943
if (caseClass.is(Module ))
939
944
caseClass.sourceModule.termRef
940
945
else caseClass.primaryConstructor.info match {
941
946
case info : PolyType =>
947
+ // Compute the the full child type by solving the subtype constraint
948
+ // `C[X1, ..., Xn] <: P`, where
949
+ //
950
+ // - P is the current `monoType`
951
+ // - C is the child class, with type parameters X1, ..., Xn
952
+ //
953
+ // Contravariant type parameters are minimized, all other type parameters are maximized.
942
954
def instantiate (implicit ctx : Context ) = {
943
955
val poly = constrained(info, untpd.EmptyTree )._1
944
956
val resType = poly.finalResultType
@@ -956,11 +968,9 @@ trait Implicits { self: Typer =>
956
968
case child => child.termRef
957
969
}
958
970
val mirrorType =
959
- defn.Mirror_SumType
960
- .refinedWith(tpnme.MonoType , monoAlias)
961
- .refinedWith(tpnme.Label , TypeAlias (label))
971
+ mirrorCore(defn.Mirror_SumType , monoType, cls.name)
962
972
.refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
963
- var modul = cls.linkedClass.sourceModule
973
+ val modul = cls.linkedClass.sourceModule
964
974
val mirrorRef =
965
975
if (modul.exists && ! cls.is(Scala2x )) ref(modul).withSpan(span)
966
976
else anonymousMirror(monoType, ExtendsSumMirror , span)
@@ -969,6 +979,9 @@ trait Implicits { self: Typer =>
969
979
EmptyTree
970
980
}
971
981
982
+ /** An implied instance for a type of the form `Mirror { type MonoType = T }`
983
+ * where `T` is a generic sum or product or singleton type.
984
+ */
972
985
lazy val synthesizedMirror : SpecialHandler =
973
986
(formal : Type , span : Span ) => implicit (ctx : Context ) =>
974
987
formal.member(tpnme.MonoType ).info match {
0 commit comments