@@ -27,6 +27,8 @@ import ErrorReporting._
27
27
import reporting .diagnostic .Message
28
28
import Inferencing .fullyDefinedType
29
29
import Trees ._
30
+ import transform .SymUtils ._
31
+ import transform .TypeUtils ._
30
32
import Hashable ._
31
33
import util .{Property , SourceFile , NoSource }
32
34
import config .Config
@@ -856,18 +858,104 @@ trait Implicits { self: Typer =>
856
858
EmptyTree
857
859
}
858
860
861
+ lazy val synthesizedProductMirror : SpecialHandler =
862
+ (formal : Type , span : Span ) => implicit (ctx : Context ) => {
863
+ formal.member(tpnme.MonoType ).info match {
864
+ case monoAlias @ TypeAlias (monoType) =>
865
+ if (monoType.termSymbol.is(CaseVal )) {
866
+ val modul = monoType.termSymbol
867
+ val caseLabel = ConstantType (Constant (modul.name.toString))
868
+ val mirrorType = defn.Mirror_SingletonType
869
+ .refinedWith(tpnme.MonoType , monoAlias)
870
+ .refinedWith(tpnme.CaseLabel , TypeAlias (caseLabel))
871
+ ref(modul).withSpan(span).cast(mirrorType)
872
+ }
873
+ else if (monoType.classSymbol.isGenericProduct) {
874
+ val cls = monoType.classSymbol
875
+ val accessors = cls.caseAccessors.filterNot(_.is(PrivateLocal ))
876
+ val elemTypes = accessors.map(monoType.memberInfo(_))
877
+ val caseLabel = ConstantType (Constant (cls.name.toString))
878
+ val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
879
+ val mirrorType =
880
+ defn.Mirror_ProductType
881
+ .refinedWith(tpnme.MonoType , monoAlias)
882
+ .refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
883
+ .refinedWith(tpnme.CaseLabel , TypeAlias (caseLabel))
884
+ .refinedWith(tpnme.ElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
885
+ val modul = cls.linkedClass.sourceModule
886
+ assert(modul.is(Module ))
887
+ ref(modul).withSpan(span).cast(mirrorType)
888
+ }
889
+ else EmptyTree
890
+ case _ => EmptyTree
891
+ }
892
+ }
893
+
894
+ lazy val synthesizedSumMirror : SpecialHandler =
895
+ (formal : Type , span : Span ) => implicit (ctx : Context ) =>
896
+ formal.member(tpnme.MonoType ).info match {
897
+ case monoAlias @ TypeAlias (monoType) if monoType.classSymbol.isGenericSum =>
898
+ val cls = monoType.classSymbol
899
+ val elemTypes = cls.children.map {
900
+ case caseClass : ClassSymbol =>
901
+ assert(caseClass.is(Case ))
902
+ if (caseClass.is(Module ))
903
+ caseClass.sourceModule.termRef
904
+ else caseClass.primaryConstructor.info match {
905
+ case info : PolyType =>
906
+ def instantiate (implicit ctx : Context ) = {
907
+ val poly = constrained(info, untpd.EmptyTree )._1
908
+ val mono @ MethodType (_) = poly.resultType
909
+ val resType = mono.finalResultType
910
+ resType <:< cls.appliedRef
911
+ val tparams = poly.paramRefs
912
+ val variances = caseClass.typeParams.map(_.paramVariance)
913
+ val instanceTypes = (tparams, variances).zipped.map((tparam, variance) =>
914
+ ctx.typeComparer.instanceType(tparam, fromBelow = variance < 0 ))
915
+ resType.substParams(poly, instanceTypes)
916
+ }
917
+ instantiate(ctx.fresh.setExploreTyperState().setOwner(caseClass))
918
+ case _ =>
919
+ caseClass.typeRef
920
+ }
921
+ case child => child.termRef
922
+ }
923
+ val mirrorType =
924
+ defn.Mirror_SumType
925
+ .refinedWith(tpnme.MonoType , monoAlias)
926
+ .refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
927
+ var modul = cls.linkedClass.sourceModule
928
+ if (! modul.exists) ???
929
+ ref(modul).withSpan(span).cast(mirrorType)
930
+ case _ =>
931
+ EmptyTree
932
+ }
933
+
934
+ lazy val synthesizedMirror : SpecialHandler =
935
+ (formal : Type , span : Span ) => implicit (ctx : Context ) =>
936
+ formal.member(tpnme.MonoType ).info match {
937
+ case monoAlias @ TypeAlias (monoType) =>
938
+ if (monoType.termSymbol.is(CaseVal ) || monoType.classSymbol.isGenericProduct)
939
+ synthesizedProductMirror(formal, span)(ctx)
940
+ else
941
+ synthesizedSumMirror(formal, span)(ctx)
942
+ }
943
+
859
944
private var mySpecialHandlers : SpecialHandlers = null
860
945
861
946
private def specialHandlers (implicit ctx : Context ) = {
862
947
if (mySpecialHandlers == null )
863
948
mySpecialHandlers = List (
864
- defn.ClassTagClass -> synthesizedClassTag,
865
- defn.QuotedTypeClass -> synthesizedTypeTag,
866
- defn.GenericClass -> synthesizedGeneric,
949
+ defn.ClassTagClass -> synthesizedClassTag,
950
+ defn.QuotedTypeClass -> synthesizedTypeTag,
951
+ defn.GenericClass -> synthesizedGeneric,
867
952
defn.TastyReflectionClass -> synthesizedTastyContext,
868
- defn.EqlClass -> synthesizedEq,
953
+ defn.EqlClass -> synthesizedEq,
869
954
defn.TupledFunctionClass -> synthesizedTupleFunction,
870
- defn.ValueOfClass -> synthesizedValueOf
955
+ defn.ValueOfClass -> synthesizedValueOf,
956
+ defn.Mirror_ProductClass -> synthesizedProductMirror,
957
+ defn.Mirror_SumClass -> synthesizedSumMirror,
958
+ defn.MirrorClass -> synthesizedMirror
871
959
)
872
960
mySpecialHandlers
873
961
}
@@ -881,7 +969,13 @@ trait Implicits { self: Typer =>
881
969
case fail @ SearchFailure (failed) =>
882
970
def trySpecialCases (handlers : SpecialHandlers ): Tree = handlers match {
883
971
case (cls, handler) :: rest =>
884
- val base = formal.baseType(cls)
972
+ def baseWithRefinements (tp : Type ): Type = tp.dealias match {
973
+ case tp @ RefinedType (parent, rname, rinfo) =>
974
+ tp.derivedRefinedType(baseWithRefinements(parent), rname, rinfo)
975
+ case _ =>
976
+ tp.baseType(cls)
977
+ }
978
+ val base = baseWithRefinements(formal)
885
979
val result =
886
980
if (base <:< formal) {
887
981
// With the subtype test we enforce that the searched type `formal` is of the right form
0 commit comments