@@ -862,7 +862,7 @@ trait Implicits { self: Typer =>
862862 /** Create an anonymous class `new Object { type MonoType = ... }`
863863 * and mark it with given attachment so that it is made into a mirror at PostTyper.
864864 */
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 ) = {
866866 val monoTypeDef = untpd.TypeDef (tpnme.MonoType , untpd.TypeTree (monoType))
867867 val newImpl = untpd.Template (
868868 constr = untpd.emptyConstructor,
@@ -874,6 +874,18 @@ trait Implicits { self: Typer =>
874874 typed(untpd.New (newImpl).withSpan(span))
875875 }
876876
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+ */
877889 lazy val synthesizedProductMirror : SpecialHandler =
878890 (formal : Type , span : Span ) => implicit (ctx : Context ) => {
879891 def mirrorFor (monoType : Type ): Tree = monoType match {
@@ -882,19 +894,13 @@ trait Implicits { self: Typer =>
882894 case _ =>
883895 if (monoType.termSymbol.is(CaseVal )) {
884896 val modul = monoType.termSymbol
885- val label = ConstantType (Constant (modul.name.toString))
886897 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)
891899 val mirrorRef = New (defn.Mirror_SingletonProxyType , ref(modul).withSpan(span) :: Nil )
892900 mirrorRef.cast(mirrorType)
893901 }
894902 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)
898904 val mirrorRef = ref(modul).withSpan(span)
899905 mirrorRef.cast(mirrorType)
900906 }
@@ -903,13 +909,10 @@ trait Implicits { self: Typer =>
903909 val cls = monoType.classSymbol
904910 val accessors = cls.caseAccessors.filterNot(_.is(PrivateLocal ))
905911 val elemTypes = accessors.map(monoType.memberInfo(_).widenExpr)
906- val label = ConstantType (Constant (cls.name.toString))
907912 val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
908913 val mirrorType =
909- defn.Mirror_ProductType
910- .refinedWith(tpnme.MonoType , TypeAlias (monoType))
914+ mirrorCore(defn.Mirror_ProductType , monoType, cls.name)
911915 .refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
912- .refinedWith(tpnme.Label , TypeAlias (label))
913916 .refinedWith(tpnme.ElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
914917 val modul = cls.linkedClass.sourceModule
915918 assert(modul.is(Module ))
@@ -926,19 +929,28 @@ trait Implicits { self: Typer =>
926929 }
927930 }
928931
932+ /** An implied instance for a type of the form `Mirror.Sum { type MonoType = T }`
933+ * where `T` is a generic sum type.
934+ */
929935 lazy val synthesizedSumMirror : SpecialHandler =
930936 (formal : Type , span : Span ) => implicit (ctx : Context ) =>
931937 formal.member(tpnme.MonoType ).info match {
932- case monoAlias @ TypeAlias (monoType) if monoType.classSymbol.isGenericSum =>
938+ case TypeAlias (monoType) if monoType.classSymbol.isGenericSum =>
933939 val cls = monoType.classSymbol
934- val label = ConstantType (Constant (cls.name.toString))
935940 val elemTypes = cls.children.map {
936941 case caseClass : ClassSymbol =>
937942 assert(caseClass.is(Case ))
938943 if (caseClass.is(Module ))
939944 caseClass.sourceModule.termRef
940945 else caseClass.primaryConstructor.info match {
941946 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.
942954 def instantiate (implicit ctx : Context ) = {
943955 val poly = constrained(info, untpd.EmptyTree )._1
944956 val resType = poly.finalResultType
@@ -956,11 +968,9 @@ trait Implicits { self: Typer =>
956968 case child => child.termRef
957969 }
958970 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)
962972 .refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
963- var modul = cls.linkedClass.sourceModule
973+ val modul = cls.linkedClass.sourceModule
964974 val mirrorRef =
965975 if (modul.exists && ! cls.is(Scala2x )) ref(modul).withSpan(span)
966976 else anonymousMirror(monoType, ExtendsSumMirror , span)
@@ -969,6 +979,9 @@ trait Implicits { self: Typer =>
969979 EmptyTree
970980 }
971981
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+ */
972985 lazy val synthesizedMirror : SpecialHandler =
973986 (formal : Type , span : Span ) => implicit (ctx : Context ) =>
974987 formal.member(tpnme.MonoType ).info match {
0 commit comments