@@ -27,6 +27,8 @@ import ErrorReporting._
2727import reporting .diagnostic .Message
2828import Inferencing .fullyDefinedType
2929import Trees ._
30+ import transform .SymUtils ._
31+ import transform .TypeUtils ._
3032import Hashable ._
3133import util .{Property , SourceFile , NoSource }
3234import config .Config
@@ -856,18 +858,104 @@ trait Implicits { self: Typer =>
856858 EmptyTree
857859 }
858860
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+
859944 private var mySpecialHandlers : SpecialHandlers = null
860945
861946 private def specialHandlers (implicit ctx : Context ) = {
862947 if (mySpecialHandlers == null )
863948 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,
867952 defn.TastyReflectionClass -> synthesizedTastyContext,
868- defn.EqlClass -> synthesizedEq,
953+ defn.EqlClass -> synthesizedEq,
869954 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
871959 )
872960 mySpecialHandlers
873961 }
@@ -881,7 +969,13 @@ trait Implicits { self: Typer =>
881969 case fail @ SearchFailure (failed) =>
882970 def trySpecialCases (handlers : SpecialHandlers ): Tree = handlers match {
883971 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)
885979 val result =
886980 if (base <:< formal) {
887981 // With the subtype test we enforce that the searched type `formal` is of the right form
0 commit comments