Skip to content

Commit 19c5d65

Browse files
committed
Supported lifted MirrorTypes
1 parent aa96f5e commit 19c5d65

File tree

2 files changed

+205
-6
lines changed

2 files changed

+205
-6
lines changed

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,16 @@ trait Implicits { self: Typer =>
911911
loop(formal)
912912
}
913913

914+
private def mkMirroredMonoType(mirroredType: HKTypeLambda)(implicit ctx: Context): Type = {
915+
val monoMap = new TypeMap {
916+
def apply(t: Type) = t match {
917+
case TypeParamRef(lambda, n) if lambda eq mirroredType => mirroredType.paramInfos(n)
918+
case t => mapOver(t)
919+
}
920+
}
921+
monoMap(mirroredType.resultType)
922+
}
923+
914924
/** An implied instance for a type of the form `Mirror.Product { type MirroredType = T }`
915925
* where `T` is a generic product type or a case object or an enum case.
916926
*/
@@ -945,9 +955,7 @@ trait Implicits { self: Typer =>
945955
mirroredType.derivedLambdaType(
946956
resType = TypeOps.nestedPairs(accessors.map(mirroredType.memberInfo(_).widenExpr))
947957
)
948-
val AppliedType(tycon, _) = mirroredType.resultType
949-
val monoType = AppliedType(tycon, mirroredType.paramInfos)
950-
(monoType, elems)
958+
(mkMirroredMonoType(mirroredType), elems)
951959
case _ =>
952960
val elems = TypeOps.nestedPairs(accessors.map(mirroredType.memberInfo(_).widenExpr))
953961
(mirroredType, elems)
@@ -1029,9 +1037,7 @@ trait Implicits { self: Typer =>
10291037
val elems = mirroredType.derivedLambdaType(
10301038
resType = TypeOps.nestedPairs(cls.children.map(solve))
10311039
)
1032-
val AppliedType(tycon, _) = mirroredType.resultType
1033-
val monoType = AppliedType(tycon, mirroredType.paramInfos)
1034-
(monoType, elems)
1040+
(mkMirroredMonoType(mirroredType), elems)
10351041
case _ =>
10361042
val elems = TypeOps.nestedPairs(cls.children.map(solve))
10371043
(mirroredType, elems)

tests/run/curried-mirror.scala

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import scala.deriving._
2+
3+
object Test extends App {
4+
case class Prod0(i: Int)
5+
6+
{
7+
val v0 = the[Mirror.Product { type MirroredType = [T] =>> Prod0 }]
8+
val v1 = v0.fromProduct(Tuple1(13))
9+
val v2: Prod0 = v1
10+
assert(v2 == Prod0(13))
11+
}
12+
13+
{
14+
val v0 = the[Mirror.Product { type MirroredType = [T, U] =>> Prod0 }]
15+
val v1 = v0.fromProduct(Tuple1(13))
16+
val v2: Prod0 = v1
17+
assert(v2 == Prod0(13))
18+
}
19+
20+
case class Prod1[A](a: A)
21+
22+
{
23+
val v0 = the[Mirror.Product { type MirroredType = [T, U] =>> Prod1[U] }]
24+
val v1 = v0.fromProduct(Tuple1(13))
25+
val v2: Prod1[_] = v1
26+
assert(v2 == Prod1(13))
27+
}
28+
29+
case class Prod2[A, B](a: A, b: B)
30+
31+
{
32+
val v0 = the[Mirror.Product { type MirroredType = Prod2 }]
33+
val v1 = v0.fromProduct((23, "foo"))
34+
val v2: Prod2[_, _] = v1
35+
assert(v2 == Prod2(23, "foo"))
36+
}
37+
38+
{
39+
val v0 = the[Mirror.Product { type MirroredType = [B] =>> Prod2[Int, B] }]
40+
val v1 = v0.fromProduct((23, "foo"))
41+
val v2: Prod2[Int, _] = v1
42+
assert(v2 == Prod2(23, "foo"))
43+
}
44+
45+
{
46+
val v0 = the[Mirror.Product { type MirroredType = Prod2[Int, String] }]
47+
val v1 = v0.fromProduct((23, "foo"))
48+
val v2: Prod2[Int, String] = v1
49+
assert(v2 == Prod2(23, "foo"))
50+
}
51+
52+
case class ProdV1[+A](a: A)
53+
54+
{
55+
val v0 = the[Mirror.Product { type MirroredType = [T, U] =>> ProdV1[U] }]
56+
val v1 = v0.fromProduct(Tuple1(13))
57+
val v2: ProdV1[_] = v1
58+
assert(v2 == ProdV1(13))
59+
}
60+
61+
case class ProdV2[+A, +B](a: A, b: B)
62+
63+
{
64+
val v0 = the[Mirror.Product { type MirroredType = ProdV2 }]
65+
val v1 = v0.fromProduct((23, "foo"))
66+
val v2: ProdV2[_, _] = v1
67+
assert(v2 == ProdV2(23, "foo"))
68+
}
69+
70+
{
71+
val v0 = the[Mirror.Product { type MirroredType = [B] =>> ProdV2[Int, B] }]
72+
val v1 = v0.fromProduct((23, "foo"))
73+
val v2: ProdV2[Int, _] = v1
74+
assert(v2 == ProdV2(23, "foo"))
75+
}
76+
77+
{
78+
val v0 = the[Mirror.Product { type MirroredType = ProdV2[Int, String] }]
79+
val v1 = v0.fromProduct((23, "foo"))
80+
val v2: ProdV2[Int, String] = v1
81+
assert(v2 == ProdV2(23, "foo"))
82+
}
83+
84+
sealed trait Sum0
85+
object Sum0 {
86+
case class Some(i: Int) extends Sum0
87+
case object None extends Sum0
88+
}
89+
90+
{
91+
val v0 = the[Mirror.Sum { type MirroredType = [T] =>> Sum0 }]
92+
val v1 = v0.ordinal(Sum0.Some(13))
93+
assert(v1 == 0)
94+
val v2 = v0.ordinal(Sum0.None)
95+
assert(v2 == 1)
96+
}
97+
98+
{
99+
val v0 = the[Mirror.Sum { type MirroredType = [T, U] =>> Sum0 }]
100+
val v1 = v0.ordinal(Sum0.Some(13))
101+
assert(v1 == 0)
102+
val v2 = v0.ordinal(Sum0.None)
103+
assert(v2 == 1)
104+
}
105+
106+
sealed trait Sum1[A]
107+
object Sum1 {
108+
case class Some[A](a: A) extends Sum1[A]
109+
case class None[A]() extends Sum1[A]
110+
}
111+
112+
{
113+
val v0 = the[Mirror.Sum { type MirroredType = [T, U] =>> Sum1[U] }]
114+
val v1 = v0.ordinal(Sum1.Some(13))
115+
assert(v1 == 0)
116+
val v2 = v0.ordinal(Sum1.None())
117+
assert(v2 == 1)
118+
}
119+
120+
sealed trait Sum2[A, B]
121+
object Sum2 {
122+
case class Left[A, B](a: A) extends Sum2[A, B]
123+
case class Right[A, B](b: B) extends Sum2[A, B]
124+
}
125+
126+
{
127+
val v0 = the[Mirror.Sum { type MirroredType = Sum2 }]
128+
val v1 = v0.ordinal(Sum2.Left(23))
129+
assert(v1 == 0)
130+
val v2 = v0.ordinal(Sum2.Right("foo"))
131+
assert(v2 == 1)
132+
}
133+
134+
{
135+
val v0 = the[Mirror.Sum { type MirroredType = [B] =>> Sum2[Int, B] }]
136+
val v1 = v0.ordinal(Sum2.Left(23))
137+
assert(v1 == 0)
138+
val v2 = v0.ordinal(Sum2.Right("foo"))
139+
assert(v2 == 1)
140+
}
141+
142+
{
143+
val v0 = the[Mirror.Sum { type MirroredType = Sum2[Int, String] }]
144+
val v1 = v0.ordinal(Sum2.Left(23))
145+
assert(v1 == 0)
146+
val v2 = v0.ordinal(Sum2.Right("foo"))
147+
assert(v2 == 1)
148+
}
149+
150+
sealed trait SumV1[+A]
151+
object SumV1 {
152+
case class Some[A](a: A) extends SumV1[A]
153+
case object None extends SumV1[Nothing]
154+
}
155+
156+
{
157+
val v0 = the[Mirror.Sum { type MirroredType = [T, U] =>> SumV1[U] }]
158+
val v1 = v0.ordinal(SumV1.Some(13))
159+
assert(v1 == 0)
160+
val v2 = v0.ordinal(SumV1.None)
161+
assert(v2 == 1)
162+
}
163+
164+
sealed trait SumV2[+A, +B]
165+
object SumV2 {
166+
case class Left[A](a: A) extends SumV2[A, Nothing]
167+
case class Right[B](b: B) extends SumV2[Nothing, B]
168+
}
169+
170+
{
171+
val v0 = the[Mirror.Sum { type MirroredType = SumV2 }]
172+
val v1 = v0.ordinal(SumV2.Left(23))
173+
assert(v1 == 0)
174+
val v2 = v0.ordinal(SumV2.Right("foo"))
175+
assert(v2 == 1)
176+
}
177+
178+
{
179+
val v0 = the[Mirror.Sum { type MirroredType = [B] =>> SumV2[Int, B] }]
180+
val v1 = v0.ordinal(SumV2.Left(23))
181+
assert(v1 == 0)
182+
val v2 = v0.ordinal(SumV2.Right("foo"))
183+
assert(v2 == 1)
184+
}
185+
186+
{
187+
val v0 = the[Mirror.Sum { type MirroredType = SumV2[Int, String] }]
188+
val v1 = v0.ordinal(SumV2.Left(23))
189+
assert(v1 == 0)
190+
val v2 = v0.ordinal(SumV2.Right("foo"))
191+
assert(v2 == 1)
192+
}
193+
}

0 commit comments

Comments
 (0)