Skip to content

Commit 64d9311

Browse files
committed
Remove the helpers in scala.deriving.
* `ArrayProduct` * `EmptyProduct` * `productElement` These helpers are not mandated by the spec, nor used by the compiler. They were used in a few tests for typeclass derivation, but it does not seem that they are fundamental. We define them in the relevant tests instead. `ArrayProduct` and `EmptyProduct` seem to be used by "unpickling" kinds of derivations. This is a fairly specific use case, and unpicklers can and should define their own. `productElement` seems to be more generally useful, but at the same time is very unsafe, and is not hard to re-implement. As it was the last non-fundamental definition remaining in `scala.deriving`, we also remove it. It could be reintroduced in the future if more widespread experience proves that it is widely useful.
1 parent f8b1c98 commit 64d9311

File tree

5 files changed

+35
-22
lines changed

5 files changed

+35
-22
lines changed

library/src/scala/deriving/Helpers.scala

Lines changed: 0 additions & 18 deletions
This file was deleted.

tests/disabled/pos-macros/i7853/JsonEncoder_1.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ object JsonEncoder {
1919
case _ => Nil
2020
}
2121

22+
private def productElement[T](x: Any, idx: Int): T =
23+
x.asInstanceOf[Product].productElement(idx).asInstanceOf[T]
24+
2225
inline def derived[T](implicit ev: Mirror.Of[T]): JsonEncoder[T] = new JsonEncoder[T] {
2326
def encode(value: T): String =
2427
inline ev match {
@@ -45,4 +48,4 @@ object JsonEncoder {
4548
given stringEncoder as JsonEncoder[String] {
4649
def encode(value: String) = value
4750
}
48-
}
51+
}

tests/pos-special/typeclass-scaling.scala

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ object typeclasses {
213213
def eql(x: T, y: T): Boolean
214214
}
215215

216+
private def productElement[T](x: Any, idx: Int): T =
217+
x.asInstanceOf[Product].productElement(idx).asInstanceOf[T]
218+
216219
object Eq {
217220
import scala.compiletime.erasedValue
218221
import compiletime._
@@ -273,6 +276,17 @@ object typeclasses {
273276

274277
def nextInt(buf: mutable.ListBuffer[Int]): Int = try buf.head finally buf.trimStart(1)
275278

279+
sealed class ArrayProduct(val elems: Array[AnyRef]) extends Product {
280+
def this(size: Int) = this(new Array[AnyRef](size))
281+
def canEqual(that: Any): Boolean = true
282+
def productElement(n: Int): Any = elems(n)
283+
def productArity: Int = elems.length
284+
override def productIterator: Iterator[Any] = elems.iterator
285+
def update(n: Int, x: Any): Unit = elems(n) = x.asInstanceOf[AnyRef]
286+
}
287+
288+
object EmptyProduct extends ArrayProduct(Array.emptyObjectArray)
289+
276290
inline def tryPickle[T](buf: mutable.ListBuffer[Int], x: T): Unit = summonInline[Pickler[T]].pickle(buf, x)
277291

278292
inline def pickleElems[Elems <: Tuple](n: Int)(buf: mutable.ListBuffer[Int], x: Any): Unit =
@@ -391,4 +405,4 @@ object Test extends App {
391405
implicitly[Pickler[E14[Int]]]
392406
implicitly[Pickler[E15[Int]]]
393407
implicitly[Pickler[E16[Int]]]
394-
}
408+
}

tests/run/deriving.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ sealed trait U
88
case class C() extends U
99

1010
object Test extends App {
11-
import deriving.{Mirror, EmptyProduct}
11+
import deriving._
1212

1313
case class AA[X >: Null <: AnyRef](x: X, y: X, z: String)
1414

@@ -21,7 +21,7 @@ object Test extends App {
2121
}
2222
summon[Mirror.Of[B.type]] match {
2323
case m: Mirror.Product =>
24-
println(m.fromProduct(EmptyProduct))
24+
println(m.fromProduct(EmptyTuple))
2525
}
2626
summon[Mirror.Of[T]] match {
2727
case m: Mirror.SumOf[T] =>

tests/run/typeclass-derivation3.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ object typeclasses {
3030
def eql(x: T, y: T): Boolean
3131
}
3232

33+
private def productElement[T](x: Any, idx: Int): T =
34+
x.asInstanceOf[Product].productElement(idx).asInstanceOf[T]
35+
3336
object Eq {
3437
import scala.compiletime.{erasedValue, summonFrom}
3538
import compiletime._
@@ -92,6 +95,17 @@ object typeclasses {
9295

9396
def nextInt(buf: mutable.ListBuffer[Int]): Int = try buf.head finally buf.trimStart(1)
9497

98+
sealed class ArrayProduct(val elems: Array[AnyRef]) extends Product {
99+
def this(size: Int) = this(new Array[AnyRef](size))
100+
def canEqual(that: Any): Boolean = true
101+
def productElement(n: Int): Any = elems(n)
102+
def productArity: Int = elems.length
103+
override def productIterator: Iterator[Any] = elems.iterator
104+
def update(n: Int, x: Any): Unit = elems(n) = x.asInstanceOf[AnyRef]
105+
}
106+
107+
object EmptyProduct extends ArrayProduct(Array.emptyObjectArray)
108+
95109
inline def tryPickle[T](buf: mutable.ListBuffer[Int], x: T): Unit = summonFrom {
96110
case pkl: Pickler[T] => pkl.pickle(buf, x)
97111
}

0 commit comments

Comments
 (0)