@@ -818,7 +818,7 @@ trait Implicits { self: Typer =>
818
818
/** Create an anonymous class `new Object { type MonoType = ... }`
819
819
* and mark it with given attachment so that it is made into a mirror at PostTyper.
820
820
*/
821
- def anonymousMirror (monoType : Type , attachment : Property .StickyKey [Unit ], span : Span )(implicit ctx : Context ) = {
821
+ private def anonymousMirror (monoType : Type , attachment : Property .StickyKey [Unit ], span : Span )(implicit ctx : Context ) = {
822
822
val monoTypeDef = untpd.TypeDef (tpnme.MonoType , untpd.TypeTree (monoType))
823
823
val newImpl = untpd.Template (
824
824
constr = untpd.emptyConstructor,
@@ -830,6 +830,18 @@ trait Implicits { self: Typer =>
830
830
typed(untpd.New (newImpl).withSpan(span))
831
831
}
832
832
833
+ /** The mirror type
834
+ *
835
+ * <parent> { MonoType = <monoType; Label = <label> }
836
+ */
837
+ private def mirrorCore (parent : Type , monoType : Type , label : Name )(implicit ctx : Context ) =
838
+ parent
839
+ .refinedWith(tpnme.MonoType , TypeAlias (monoType))
840
+ .refinedWith(tpnme.Label , TypeAlias (ConstantType (Constant (label.toString))))
841
+
842
+ /** An implied instance for a type of the form `Mirror.Product { type MonoType = T }`
843
+ * where `T` is a generic product type or a case object or an enum case.
844
+ */
833
845
lazy val synthesizedProductMirror : SpecialHandler =
834
846
(formal : Type , span : Span ) => implicit (ctx : Context ) => {
835
847
def mirrorFor (monoType : Type ): Tree = monoType match {
@@ -838,19 +850,13 @@ trait Implicits { self: Typer =>
838
850
case _ =>
839
851
if (monoType.termSymbol.is(CaseVal )) {
840
852
val modul = monoType.termSymbol
841
- val label = ConstantType (Constant (modul.name.toString))
842
853
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))
854
+ val mirrorType = mirrorCore(defn.Mirror_SingletonProxyType , monoType, modul.name)
847
855
val mirrorRef = New (defn.Mirror_SingletonProxyType , ref(modul).withSpan(span) :: Nil )
848
856
mirrorRef.cast(mirrorType)
849
857
}
850
858
else {
851
- val mirrorType = defn.Mirror_SingletonType
852
- .refinedWith(tpnme.MonoType , TypeAlias (monoType))
853
- .refinedWith(tpnme.Label , TypeAlias (label))
859
+ val mirrorType = mirrorCore(defn.Mirror_SingletonType , monoType, modul.name)
854
860
val mirrorRef = ref(modul).withSpan(span)
855
861
mirrorRef.cast(mirrorType)
856
862
}
@@ -859,13 +865,10 @@ trait Implicits { self: Typer =>
859
865
val cls = monoType.classSymbol
860
866
val accessors = cls.caseAccessors.filterNot(_.is(PrivateLocal ))
861
867
val elemTypes = accessors.map(monoType.memberInfo(_).widenExpr)
862
- val label = ConstantType (Constant (cls.name.toString))
863
868
val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
864
869
val mirrorType =
865
- defn.Mirror_ProductType
866
- .refinedWith(tpnme.MonoType , TypeAlias (monoType))
870
+ mirrorCore(defn.Mirror_ProductType , monoType, cls.name)
867
871
.refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
868
- .refinedWith(tpnme.Label , TypeAlias (label))
869
872
.refinedWith(tpnme.ElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
870
873
val modul = cls.linkedClass.sourceModule
871
874
assert(modul.is(Module ))
@@ -882,19 +885,28 @@ trait Implicits { self: Typer =>
882
885
}
883
886
}
884
887
888
+ /** An implied instance for a type of the form `Mirror.Sum { type MonoType = T }`
889
+ * where `T` is a generic sum type.
890
+ */
885
891
lazy val synthesizedSumMirror : SpecialHandler =
886
892
(formal : Type , span : Span ) => implicit (ctx : Context ) =>
887
893
formal.member(tpnme.MonoType ).info match {
888
- case monoAlias @ TypeAlias (monoType) if monoType.classSymbol.isGenericSum =>
894
+ case TypeAlias (monoType) if monoType.classSymbol.isGenericSum =>
889
895
val cls = monoType.classSymbol
890
- val label = ConstantType (Constant (cls.name.toString))
891
896
val elemTypes = cls.children.map {
892
897
case caseClass : ClassSymbol =>
893
898
assert(caseClass.is(Case ))
894
899
if (caseClass.is(Module ))
895
900
caseClass.sourceModule.termRef
896
901
else caseClass.primaryConstructor.info match {
897
902
case info : PolyType =>
903
+ // Compute the the full child type by solving the subtype constraint
904
+ // `C[X1, ..., Xn] <: P`, where
905
+ //
906
+ // - P is the current `monoType`
907
+ // - C is the child class, with type parameters X1, ..., Xn
908
+ //
909
+ // Contravariant type parameters are minimized, all other type parameters are maximized.
898
910
def instantiate (implicit ctx : Context ) = {
899
911
val poly = constrained(info, untpd.EmptyTree )._1
900
912
val resType = poly.finalResultType
@@ -912,11 +924,9 @@ trait Implicits { self: Typer =>
912
924
case child => child.termRef
913
925
}
914
926
val mirrorType =
915
- defn.Mirror_SumType
916
- .refinedWith(tpnme.MonoType , monoAlias)
917
- .refinedWith(tpnme.Label , TypeAlias (label))
927
+ mirrorCore(defn.Mirror_SumType , monoType, cls.name)
918
928
.refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
919
- var modul = cls.linkedClass.sourceModule
929
+ val modul = cls.linkedClass.sourceModule
920
930
val mirrorRef =
921
931
if (modul.exists && ! cls.is(Scala2x )) ref(modul).withSpan(span)
922
932
else anonymousMirror(monoType, ExtendsSumMirror , span)
@@ -925,6 +935,9 @@ trait Implicits { self: Typer =>
925
935
EmptyTree
926
936
}
927
937
938
+ /** An implied instance for a type of the form `Mirror { type MonoType = T }`
939
+ * where `T` is a generic sum or product or singleton type.
940
+ */
928
941
lazy val synthesizedMirror : SpecialHandler =
929
942
(formal : Type , span : Span ) => implicit (ctx : Context ) =>
930
943
formal.member(tpnme.MonoType ).info match {
0 commit comments