@@ -884,15 +884,15 @@ trait Implicits { self: Typer =>
884884 *
885885 * <parent> {
886886 * MirroredMonoType = <monoType>
887- * MirroredTypeConstrictor = <tycon >
887+ * MirroredType = <mirroredType >
888888 * MirroredLabel = <label> }
889+ * }
889890 */
890- private def mirrorCore (parentClass : ClassSymbol , monoType : Type , mirroredType : Type , label : Name )(implicit ctx : Context ) = {
891- parentClass.typeRef
891+ private def mirrorCore (parentClass : ClassSymbol , monoType : Type , mirroredType : Type , label : Name , formal : Type )(implicit ctx : Context ) =
892+ formal & parentClass.typeRef
892893 .refinedWith(tpnme.MirroredMonoType , TypeAlias (monoType))
893894 .refinedWith(tpnme.MirroredType , TypeAlias (mirroredType))
894895 .refinedWith(tpnme.MirroredLabel , TypeAlias (ConstantType (Constant (label.toString))))
895- }
896896
897897 /** A path referencing the companion of class type `clsType` */
898898 private def companionPath (clsType : Type , span : Span )(implicit ctx : Context ) = {
@@ -901,6 +901,16 @@ trait Implicits { self: Typer =>
901901 ref.withSpan(span)
902902 }
903903
904+ private def checkFormal (formal : Type )(implicit ctx : Context ): Boolean = {
905+ @ tailrec
906+ def loop (tp : Type ): Boolean = tp match {
907+ case RefinedType (parent, _, _ : TypeBounds ) => loop(parent)
908+ case RefinedType (_, _, _) => false
909+ case _ => true
910+ }
911+ loop(formal)
912+ }
913+
904914 /** An implied instance for a type of the form `Mirror.Product { type MirroredType = T }`
905915 * where `T` is a generic product type or a case object or an enum case.
906916 */
@@ -916,12 +926,12 @@ trait Implicits { self: Typer =>
916926 val module = mirroredType.termSymbol
917927 val modulePath = pathFor(mirroredType).withSpan(span)
918928 if (module.info.classSymbol.is(Scala2x )) {
919- val mirrorType = mirrorCore(defn.Mirror_SingletonProxyClass , mirroredType, mirroredType, module.name)
929+ val mirrorType = mirrorCore(defn.Mirror_SingletonProxyClass , mirroredType, mirroredType, module.name, formal )
920930 val mirrorRef = New (defn.Mirror_SingletonProxyClass .typeRef, modulePath :: Nil )
921931 mirrorRef.cast(mirrorType)
922932 }
923933 else {
924- val mirrorType = mirrorCore(defn.Mirror_SingletonClass , mirroredType, mirroredType, module.name)
934+ val mirrorType = mirrorCore(defn.Mirror_SingletonClass , mirroredType, mirroredType, module.name, formal )
925935 modulePath.cast(mirrorType)
926936 }
927937 }
@@ -943,7 +953,7 @@ trait Implicits { self: Typer =>
943953 (mirroredType, elems)
944954 }
945955 val mirrorType =
946- mirrorCore(defn.Mirror_ProductClass , monoType, mirroredType, cls.name)
956+ mirrorCore(defn.Mirror_ProductClass , monoType, mirroredType, cls.name, formal )
947957 .refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
948958 .refinedWith(tpnme.MirroredElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
949959 val mirrorRef =
@@ -955,85 +965,89 @@ trait Implicits { self: Typer =>
955965 }
956966 }
957967
958- formal.member(tpnme.MirroredType ).info match {
959- case TypeBounds (mirroredType, _) => mirrorFor(mirroredType)
960- case other => EmptyTree
961- }
968+ if (! checkFormal(formal)) EmptyTree
969+ else
970+ formal.member(tpnme.MirroredType ).info match {
971+ case TypeBounds (mirroredType, _) => mirrorFor(mirroredType)
972+ case other => EmptyTree
973+ }
962974 }
963975
964976 /** An implied instance for a type of the form `Mirror.Sum { type MirroredType = T }`
965977 * where `T` is a generic sum type.
966978 */
967979 lazy val synthesizedSumMirror : SpecialHandler =
968980 (formal, span) => implicit ctx => {
969- formal.member(tpnme.MirroredType ).info match {
970- case TypeBounds (mirroredType0, _) =>
971- val mirroredType = mirroredType0.stripTypeVar
972- if (mirroredType.classSymbol.isGenericSum) {
973- val cls = mirroredType.classSymbol
974- val elemLabels = cls.children.map(c => ConstantType (Constant (c.name.toString)))
975-
976- def solve (sym : Symbol ): Type = sym match {
977- case caseClass : ClassSymbol =>
978- assert(caseClass.is(Case ))
979- if (caseClass.is(Module ))
980- caseClass.sourceModule.termRef
981- else {
982- caseClass.primaryConstructor.info match {
983- case info : PolyType =>
984- // Compute the the full child type by solving the subtype constraint
985- // `C[X1, ..., Xn] <: P`, where
986- //
987- // - P is the current `mirroredType`
988- // - C is the child class, with type parameters X1, ..., Xn
989- //
990- // Contravariant type parameters are minimized, all other type parameters are maximized.
991- def instantiate (implicit ctx : Context ) = {
992- val poly = constrained(info, untpd.EmptyTree )._1
993- val resType = poly.finalResultType
994- val target = mirroredType match {
995- case tp : HKTypeLambda => tp.resultType
996- case tp => tp
981+ if (! checkFormal(formal)) EmptyTree
982+ else
983+ formal.member(tpnme.MirroredType ).info match {
984+ case TypeBounds (mirroredType0, _) =>
985+ val mirroredType = mirroredType0.stripTypeVar
986+ if (mirroredType.classSymbol.isGenericSum) {
987+ val cls = mirroredType.classSymbol
988+ val elemLabels = cls.children.map(c => ConstantType (Constant (c.name.toString)))
989+
990+ def solve (sym : Symbol ): Type = sym match {
991+ case caseClass : ClassSymbol =>
992+ assert(caseClass.is(Case ))
993+ if (caseClass.is(Module ))
994+ caseClass.sourceModule.termRef
995+ else {
996+ caseClass.primaryConstructor.info match {
997+ case info : PolyType =>
998+ // Compute the the full child type by solving the subtype constraint
999+ // `C[X1, ..., Xn] <: P`, where
1000+ //
1001+ // - P is the current `mirroredType`
1002+ // - C is the child class, with type parameters X1, ..., Xn
1003+ //
1004+ // Contravariant type parameters are minimized, all other type parameters are maximized.
1005+ def instantiate (implicit ctx : Context ) = {
1006+ val poly = constrained(info, untpd.EmptyTree )._1
1007+ val resType = poly.finalResultType
1008+ val target = mirroredType match {
1009+ case tp : HKTypeLambda => tp.resultType
1010+ case tp => tp
1011+ }
1012+ resType <:< target
1013+ val tparams = poly.paramRefs
1014+ val variances = caseClass.typeParams.map(_.paramVariance)
1015+ val instanceTypes = (tparams, variances).zipped.map((tparam, variance) =>
1016+ ctx.typeComparer.instanceType(tparam, fromBelow = variance < 0 ))
1017+ resType.substParams(poly, instanceTypes)
9971018 }
998- resType <:< target
999- val tparams = poly.paramRefs
1000- val variances = caseClass.typeParams.map(_.paramVariance)
1001- val instanceTypes = (tparams, variances).zipped.map((tparam, variance) =>
1002- ctx.typeComparer.instanceType(tparam, fromBelow = variance < 0 ))
1003- resType.substParams(poly, instanceTypes)
1004- }
1005- instantiate(ctx.fresh.setExploreTyperState().setOwner(caseClass))
1006- case _ =>
1007- caseClass.typeRef
1019+ instantiate(ctx.fresh.setExploreTyperState().setOwner(caseClass))
1020+ case _ =>
1021+ caseClass.typeRef
1022+ }
10081023 }
1009- }
1010- case child => child.termRef
1011- }
1024+ case child => child.termRef
1025+ }
10121026
1013- val (monoType, elemsType) = mirroredType match {
1014- case mirroredType : HKTypeLambda =>
1015- val elems = mirroredType.derivedLambdaType(
1016- resType = TypeOps .nestedPairs(cls.children.map(solve))
1017- )
1018- val AppliedType (tycon, _) = mirroredType.resultType
1019- val monoType = AppliedType (tycon, mirroredType.paramInfos)
1020- (monoType, elems)
1021- case _ =>
1022- val elems = TypeOps .nestedPairs(cls.children.map(solve))
1023- (mirroredType, elems)
1024- }
1027+ val (monoType, elemsType) = mirroredType match {
1028+ case mirroredType : HKTypeLambda =>
1029+ val elems = mirroredType.derivedLambdaType(
1030+ resType = TypeOps .nestedPairs(cls.children.map(solve))
1031+ )
1032+ val AppliedType (tycon, _) = mirroredType.resultType
1033+ val monoType = AppliedType (tycon, mirroredType.paramInfos)
1034+ (monoType, elems)
1035+ case _ =>
1036+ val elems = TypeOps .nestedPairs(cls.children.map(solve))
1037+ (mirroredType, elems)
1038+ }
10251039
1026- val mirrorType =
1027- mirrorCore(defn.Mirror_SumClass , monoType, mirroredType, cls.name)
1028- .refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
1029- .refinedWith(tpnme.MirroredElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
1030- val mirrorRef =
1031- if (cls.linkedClass.exists && ! cls.is(Scala2x )) companionPath(mirroredType, span)
1032- else anonymousMirror(monoType, ExtendsSumMirror , span)
1033- mirrorRef.cast(mirrorType)
1034- } else EmptyTree
1035- case _ => EmptyTree
1036- }
1040+ val mirrorType =
1041+ mirrorCore(defn.Mirror_SumClass , monoType, mirroredType, cls.name, formal )
1042+ .refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
1043+ .refinedWith(tpnme.MirroredElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
1044+ val mirrorRef =
1045+ if (cls.linkedClass.exists && ! cls.is(Scala2x )) companionPath(mirroredType, span)
1046+ else anonymousMirror(monoType, ExtendsSumMirror , span)
1047+ mirrorRef.cast(mirrorType)
1048+ } else EmptyTree
1049+ case _ => EmptyTree
1050+ }
10371051 }
10381052
10391053 /** An implied instance for a type of the form `Mirror { type MirroredType = T }`
0 commit comments