Skip to content

Commit fdf36a0

Browse files
Merge pull request #14114 from mpilquist/topic/mirror-from-product-typed
Add typed versions of Mirror.ProductOf#fromProduct
2 parents 5109909 + 6e6e0d2 commit fdf36a0

File tree

6 files changed

+37
-1
lines changed

6 files changed

+37
-1
lines changed

library/src/scala/deriving/Mirror.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,15 @@ object Mirror {
4949
type Of[T] = Mirror { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple }
5050
type ProductOf[T] = Mirror.Product { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple }
5151
type SumOf[T] = Mirror.Sum { type MirroredType = T; type MirroredMonoType = T; type MirroredElemTypes <: Tuple }
52+
53+
extension [T](p: ProductOf[T])
54+
/** Create a new instance of type `T` with elements taken from product `a`. */
55+
@annotation.experimental
56+
def fromProductTyped[A <: scala.Product, Elems <: p.MirroredElemTypes](a: A)(using m: ProductOf[A] { type MirroredElemTypes = Elems }): T =
57+
p.fromProduct(a)
58+
59+
/** Create a new instance of type `T` with elements taken from tuple `t`. */
60+
@annotation.experimental
61+
def fromTuple(t: p.MirroredElemTypes): T =
62+
p.fromProduct(t)
5263
}

project/MiMaFilters.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ object MiMaFilters {
1717
ProblemFilters.exclude[MissingClassProblem]("scala.compiletime.ops.long$"),
1818
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#CompilationInfoModule.XmacroSettings"),
1919
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#CompilationInfoModule.XmacroSettings"),
20+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.deriving.Mirror.fromProductTyped"),
21+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.deriving.Mirror.fromTuple"),
2022

2123
// Private to the compiler - needed for forward binary compatibility
2224
ProblemFilters.exclude[MissingClassProblem]("scala.annotation.since")
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import deriving.Mirror
2+
3+
case class A(x: Int, y: String)
4+
case class B(a: Any, b: Any)
5+
object A:
6+
def f = summon[Mirror.ProductOf[A]].fromProductTyped((1, 2)) // error
7+
def g = summon[Mirror.ProductOf[A]].fromTuple((1, 2)) // error
8+
def h = summon[Mirror.ProductOf[B]].fromProductTyped(A(1, ""))
9+
def i = summon[Mirror.ProductOf[A]].fromProductTyped(B(1, "")) // error
10+

tests/neg/deriving.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ sealed trait B derives Generic // error: cannot take shape, its subclass class D
1313

1414
class D(x: Int, y: String) extends B
1515

16-
1716
class E derives Generic // error: cannot take shape, it is neither sealed nor a case class
1817

1918
sealed trait F derives Generic // error: cannot take shape, it has anonymous or inaccessible subclasses
@@ -23,3 +22,4 @@ object G {
2322
case class H() extends F
2423
}
2524
}
25+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
case class A(x: Option[Int], y: Option[Any])
2+
case class B(x: Some[Int], y: Some[Boolean])
3+
4+
object Test extends App:
5+
import deriving.*
6+
7+
val ma = summon[Mirror.ProductOf[A]]
8+
9+
ma.fromProductTyped(B(Some(1), Some(true)))
10+
ma.fromProductTyped((Some(1), Some(false)))
11+

tests/run/deriving.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ object Test extends App {
1313
case class AA[X >: Null <: AnyRef](x: X, y: X, z: String)
1414

1515
println(summon[Mirror.ProductOf[A]].fromProduct(A(1, 2)))
16+
summon[Mirror.ProductOf[A]].fromProductTyped(A(1, 2))
17+
summon[Mirror.ProductOf[A]].fromTuple((1, 2))
1618
assert(summon[Mirror.SumOf[T]].ordinal(A(1, 2)) == 0)
1719
assert(summon[Mirror.Sum { type MirroredType = T }].ordinal(B) == 1)
1820
summon[Mirror.Of[A]] match {

0 commit comments

Comments
 (0)