@@ -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
@@ -812,17 +814,103 @@ trait Implicits { self: Typer =>
812
814
EmptyTree
813
815
}
814
816
817
+ lazy val synthesizedProductMirror : SpecialHandler =
818
+ (formal : Type , span : Span ) => implicit (ctx : Context ) => {
819
+ formal.member(tpnme.MonoType ).info match {
820
+ case monoAlias @ TypeAlias (monoType) =>
821
+ if (monoType.termSymbol.is(CaseVal )) {
822
+ val modul = monoType.termSymbol
823
+ val caseLabel = ConstantType (Constant (modul.name.toString))
824
+ val mirrorType = defn.Mirror_SingletonType
825
+ .refinedWith(tpnme.MonoType , monoAlias)
826
+ .refinedWith(tpnme.CaseLabel , TypeAlias (caseLabel))
827
+ ref(modul).withSpan(span).cast(mirrorType)
828
+ }
829
+ else if (monoType.classSymbol.isGenericProduct) {
830
+ val cls = monoType.classSymbol
831
+ val accessors = cls.caseAccessors.filterNot(_.is(PrivateLocal ))
832
+ val elemTypes = accessors.map(monoType.memberInfo(_))
833
+ val caseLabel = ConstantType (Constant (cls.name.toString))
834
+ val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
835
+ val mirrorType =
836
+ defn.Mirror_ProductType
837
+ .refinedWith(tpnme.MonoType , monoAlias)
838
+ .refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
839
+ .refinedWith(tpnme.CaseLabel , TypeAlias (caseLabel))
840
+ .refinedWith(tpnme.ElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
841
+ val modul = cls.linkedClass.sourceModule
842
+ assert(modul.is(Module ))
843
+ ref(modul).withSpan(span).cast(mirrorType)
844
+ }
845
+ else EmptyTree
846
+ case _ => EmptyTree
847
+ }
848
+ }
849
+
850
+ lazy val synthesizedSumMirror : SpecialHandler =
851
+ (formal : Type , span : Span ) => implicit (ctx : Context ) =>
852
+ formal.member(tpnme.MonoType ).info match {
853
+ case monoAlias @ TypeAlias (monoType) if monoType.classSymbol.isGenericSum =>
854
+ val cls = monoType.classSymbol
855
+ val elemTypes = cls.children.map {
856
+ case caseClass : ClassSymbol =>
857
+ assert(caseClass.is(Case ))
858
+ if (caseClass.is(Module ))
859
+ caseClass.sourceModule.termRef
860
+ else caseClass.primaryConstructor.info match {
861
+ case info : PolyType =>
862
+ def instantiate (implicit ctx : Context ) = {
863
+ val poly = constrained(info, untpd.EmptyTree )._1
864
+ val mono @ MethodType (_) = poly.resultType
865
+ val resType = mono.finalResultType
866
+ resType <:< cls.appliedRef
867
+ val tparams = poly.paramRefs
868
+ val variances = caseClass.typeParams.map(_.paramVariance)
869
+ val instanceTypes = (tparams, variances).zipped.map((tparam, variance) =>
870
+ ctx.typeComparer.instanceType(tparam, fromBelow = variance < 0 ))
871
+ resType.substParams(poly, instanceTypes)
872
+ }
873
+ instantiate(ctx.fresh.setExploreTyperState().setOwner(caseClass))
874
+ case _ =>
875
+ caseClass.typeRef
876
+ }
877
+ case child => child.termRef
878
+ }
879
+ val mirrorType =
880
+ defn.Mirror_SumType
881
+ .refinedWith(tpnme.MonoType , monoAlias)
882
+ .refinedWith(tpnme.ElemTypes , TypeAlias (TypeOps .nestedPairs(elemTypes)))
883
+ var modul = cls.linkedClass.sourceModule
884
+ if (! modul.exists) ???
885
+ ref(modul).withSpan(span).cast(mirrorType)
886
+ case _ =>
887
+ EmptyTree
888
+ }
889
+
890
+ lazy val synthesizedMirror : SpecialHandler =
891
+ (formal : Type , span : Span ) => implicit (ctx : Context ) =>
892
+ formal.member(tpnme.MonoType ).info match {
893
+ case monoAlias @ TypeAlias (monoType) =>
894
+ if (monoType.termSymbol.is(CaseVal ) || monoType.classSymbol.isGenericProduct)
895
+ synthesizedProductMirror(formal, span)(ctx)
896
+ else
897
+ synthesizedSumMirror(formal, span)(ctx)
898
+ }
899
+
815
900
private var mySpecialHandlers : SpecialHandlers = null
816
901
817
902
private def specialHandlers (implicit ctx : Context ) = {
818
903
if (mySpecialHandlers == null )
819
904
mySpecialHandlers = List (
820
- defn.ClassTagClass -> synthesizedClassTag,
821
- defn.QuotedTypeClass -> synthesizedTypeTag,
822
- defn.GenericClass -> synthesizedGeneric,
905
+ defn.ClassTagClass -> synthesizedClassTag,
906
+ defn.QuotedTypeClass -> synthesizedTypeTag,
907
+ defn.GenericClass -> synthesizedGeneric,
823
908
defn.TastyReflectionClass -> synthesizedTastyContext,
824
- defn.EqlClass -> synthesizedEq,
825
- defn.ValueOfClass -> synthesizedValueOf
909
+ defn.EqlClass -> synthesizedEq,
910
+ defn.ValueOfClass -> synthesizedValueOf,
911
+ defn.Mirror_ProductClass -> synthesizedProductMirror,
912
+ defn.Mirror_SumClass -> synthesizedSumMirror,
913
+ defn.MirrorClass -> synthesizedMirror
826
914
)
827
915
mySpecialHandlers
828
916
}
@@ -836,7 +924,14 @@ trait Implicits { self: Typer =>
836
924
case fail @ SearchFailure (failed) =>
837
925
def trySpecialCases (handlers : SpecialHandlers ): Tree = handlers match {
838
926
case (cls, handler) :: rest =>
839
- val base = formal.baseType(cls)
927
+ def baseWithRefinements (tp : Type ): Type = tp.dealias match {
928
+ case tp @ RefinedType (parent, rname, rinfo) =>
929
+ tp.derivedRefinedType(baseWithRefinements(parent), rname, rinfo)
930
+ case _ =>
931
+ tp.baseType(cls)
932
+ }
933
+ val base = baseWithRefinements(formal)
934
+ println(i " try special $formal/ $cls/ $base" )
840
935
val result =
841
936
if (base <:< formal) {
842
937
// With the subtype test we enforce that the searched type `formal` is of the right form
0 commit comments