Skip to content

Commit f24e247

Browse files
oderskymilessabin
authored andcommitted
Polishings
1 parent eda4232 commit f24e247

File tree

1 file changed

+32
-19
lines changed

1 file changed

+32
-19
lines changed

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,7 @@ trait Implicits { self: Typer =>
862862
/** Create an anonymous class `new Object { type MonoType = ... }`
863863
* and mark it with given attachment so that it is made into a mirror at PostTyper.
864864
*/
865-
def anonymousMirror(monoType: Type, attachment: Property.StickyKey[Unit], span: Span)(implicit ctx: Context) = {
865+
private def anonymousMirror(monoType: Type, attachment: Property.StickyKey[Unit], span: Span)(implicit ctx: Context) = {
866866
val monoTypeDef = untpd.TypeDef(tpnme.MonoType, untpd.TypeTree(monoType))
867867
val newImpl = untpd.Template(
868868
constr = untpd.emptyConstructor,
@@ -874,6 +874,18 @@ trait Implicits { self: Typer =>
874874
typed(untpd.New(newImpl).withSpan(span))
875875
}
876876

877+
/** The mirror type
878+
*
879+
* <parent> { MonoType = <monoType; Label = <label> }
880+
*/
881+
private def mirrorCore(parent: Type, monoType: Type, label: Name)(implicit ctx: Context) =
882+
parent
883+
.refinedWith(tpnme.MonoType, TypeAlias(monoType))
884+
.refinedWith(tpnme.Label, TypeAlias(ConstantType(Constant(label.toString))))
885+
886+
/** An implied instance for a type of the form `Mirror.Product { type MonoType = T }`
887+
* where `T` is a generic product type or a case object or an enum case.
888+
*/
877889
lazy val synthesizedProductMirror: SpecialHandler =
878890
(formal: Type, span: Span) => implicit (ctx: Context) => {
879891
def mirrorFor(monoType: Type): Tree = monoType match {
@@ -882,19 +894,13 @@ trait Implicits { self: Typer =>
882894
case _ =>
883895
if (monoType.termSymbol.is(CaseVal)) {
884896
val modul = monoType.termSymbol
885-
val label = ConstantType(Constant(modul.name.toString))
886897
if (modul.info.classSymbol.is(Scala2x)) {
887-
val mirrorType =
888-
defn.Mirror_SingletonProxyType
889-
.refinedWith(tpnme.MonoType, TypeAlias(monoType))
890-
.refinedWith(tpnme.Label, TypeAlias(label))
898+
val mirrorType = mirrorCore(defn.Mirror_SingletonProxyType, monoType, modul.name)
891899
val mirrorRef = New(defn.Mirror_SingletonProxyType, ref(modul).withSpan(span) :: Nil)
892900
mirrorRef.cast(mirrorType)
893901
}
894902
else {
895-
val mirrorType = defn.Mirror_SingletonType
896-
.refinedWith(tpnme.MonoType, TypeAlias(monoType))
897-
.refinedWith(tpnme.Label, TypeAlias(label))
903+
val mirrorType = mirrorCore(defn.Mirror_SingletonType, monoType, modul.name)
898904
val mirrorRef = ref(modul).withSpan(span)
899905
mirrorRef.cast(mirrorType)
900906
}
@@ -903,13 +909,10 @@ trait Implicits { self: Typer =>
903909
val cls = monoType.classSymbol
904910
val accessors = cls.caseAccessors.filterNot(_.is(PrivateLocal))
905911
val elemTypes = accessors.map(monoType.memberInfo(_).widenExpr)
906-
val label = ConstantType(Constant(cls.name.toString))
907912
val elemLabels = accessors.map(acc => ConstantType(Constant(acc.name.toString)))
908913
val mirrorType =
909-
defn.Mirror_ProductType
910-
.refinedWith(tpnme.MonoType, TypeAlias(monoType))
914+
mirrorCore(defn.Mirror_ProductType, monoType, cls.name)
911915
.refinedWith(tpnme.ElemTypes, TypeAlias(TypeOps.nestedPairs(elemTypes)))
912-
.refinedWith(tpnme.Label, TypeAlias(label))
913916
.refinedWith(tpnme.ElemLabels, TypeAlias(TypeOps.nestedPairs(elemLabels)))
914917
val modul = cls.linkedClass.sourceModule
915918
assert(modul.is(Module))
@@ -926,19 +929,28 @@ trait Implicits { self: Typer =>
926929
}
927930
}
928931

932+
/** An implied instance for a type of the form `Mirror.Sum { type MonoType = T }`
933+
* where `T` is a generic sum type.
934+
*/
929935
lazy val synthesizedSumMirror: SpecialHandler =
930936
(formal: Type, span: Span) => implicit (ctx: Context) =>
931937
formal.member(tpnme.MonoType).info match {
932-
case monoAlias @ TypeAlias(monoType) if monoType.classSymbol.isGenericSum =>
938+
case TypeAlias(monoType) if monoType.classSymbol.isGenericSum =>
933939
val cls = monoType.classSymbol
934-
val label = ConstantType(Constant(cls.name.toString))
935940
val elemTypes = cls.children.map {
936941
case caseClass: ClassSymbol =>
937942
assert(caseClass.is(Case))
938943
if (caseClass.is(Module))
939944
caseClass.sourceModule.termRef
940945
else caseClass.primaryConstructor.info match {
941946
case info: PolyType =>
947+
// Compute the the full child type by solving the subtype constraint
948+
// `C[X1, ..., Xn] <: P`, where
949+
//
950+
// - P is the current `monoType`
951+
// - C is the child class, with type parameters X1, ..., Xn
952+
//
953+
// Contravariant type parameters are minimized, all other type parameters are maximized.
942954
def instantiate(implicit ctx: Context) = {
943955
val poly = constrained(info, untpd.EmptyTree)._1
944956
val resType = poly.finalResultType
@@ -956,11 +968,9 @@ trait Implicits { self: Typer =>
956968
case child => child.termRef
957969
}
958970
val mirrorType =
959-
defn.Mirror_SumType
960-
.refinedWith(tpnme.MonoType, monoAlias)
961-
.refinedWith(tpnme.Label, TypeAlias(label))
971+
mirrorCore(defn.Mirror_SumType, monoType, cls.name)
962972
.refinedWith(tpnme.ElemTypes, TypeAlias(TypeOps.nestedPairs(elemTypes)))
963-
var modul = cls.linkedClass.sourceModule
973+
val modul = cls.linkedClass.sourceModule
964974
val mirrorRef =
965975
if (modul.exists && !cls.is(Scala2x)) ref(modul).withSpan(span)
966976
else anonymousMirror(monoType, ExtendsSumMirror, span)
@@ -969,6 +979,9 @@ trait Implicits { self: Typer =>
969979
EmptyTree
970980
}
971981

982+
/** An implied instance for a type of the form `Mirror { type MonoType = T }`
983+
* where `T` is a generic sum or product or singleton type.
984+
*/
972985
lazy val synthesizedMirror: SpecialHandler =
973986
(formal: Type, span: Span) => implicit (ctx: Context) =>
974987
formal.member(tpnme.MonoType).info match {

0 commit comments

Comments
 (0)