@@ -884,15 +884,15 @@ trait Implicits { self: Typer =>
884
884
*
885
885
* <parent> {
886
886
* MirroredMonoType = <monoType>
887
- * MirroredTypeConstrictor = <tycon >
887
+ * MirroredType = <mirroredType >
888
888
* MirroredLabel = <label> }
889
+ * }
889
890
*/
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
892
893
.refinedWith(tpnme.MirroredMonoType , TypeAlias (monoType))
893
894
.refinedWith(tpnme.MirroredType , TypeAlias (mirroredType))
894
895
.refinedWith(tpnme.MirroredLabel , TypeAlias (ConstantType (Constant (label.toString))))
895
- }
896
896
897
897
/** A path referencing the companion of class type `clsType` */
898
898
private def companionPath (clsType : Type , span : Span )(implicit ctx : Context ) = {
@@ -901,6 +901,16 @@ trait Implicits { self: Typer =>
901
901
ref.withSpan(span)
902
902
}
903
903
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
+
904
914
/** An implied instance for a type of the form `Mirror.Product { type MirroredType = T }`
905
915
* where `T` is a generic product type or a case object or an enum case.
906
916
*/
@@ -916,12 +926,12 @@ trait Implicits { self: Typer =>
916
926
val module = mirroredType.termSymbol
917
927
val modulePath = pathFor(mirroredType).withSpan(span)
918
928
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 )
920
930
val mirrorRef = New (defn.Mirror_SingletonProxyClass .typeRef, modulePath :: Nil )
921
931
mirrorRef.cast(mirrorType)
922
932
}
923
933
else {
924
- val mirrorType = mirrorCore(defn.Mirror_SingletonClass , mirroredType, mirroredType, module.name)
934
+ val mirrorType = mirrorCore(defn.Mirror_SingletonClass , mirroredType, mirroredType, module.name, formal )
925
935
modulePath.cast(mirrorType)
926
936
}
927
937
}
@@ -943,7 +953,7 @@ trait Implicits { self: Typer =>
943
953
(mirroredType, elems)
944
954
}
945
955
val mirrorType =
946
- mirrorCore(defn.Mirror_ProductClass , monoType, mirroredType, cls.name)
956
+ mirrorCore(defn.Mirror_ProductClass , monoType, mirroredType, cls.name, formal )
947
957
.refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
948
958
.refinedWith(tpnme.MirroredElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
949
959
val mirrorRef =
@@ -955,85 +965,89 @@ trait Implicits { self: Typer =>
955
965
}
956
966
}
957
967
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
+ }
962
974
}
963
975
964
976
/** An implied instance for a type of the form `Mirror.Sum { type MirroredType = T }`
965
977
* where `T` is a generic sum type.
966
978
*/
967
979
lazy val synthesizedSumMirror : SpecialHandler =
968
980
(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)
997
1018
}
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
+ }
1008
1023
}
1009
- }
1010
- case child => child.termRef
1011
- }
1024
+ case child => child.termRef
1025
+ }
1012
1026
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
+ }
1025
1039
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
+ }
1037
1051
}
1038
1052
1039
1053
/** An implied instance for a type of the form `Mirror { type MirroredType = T }`
0 commit comments