-
Notifications
You must be signed in to change notification settings - Fork 542
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatic derivation for recursive types is broken in Scala 3 #1980
Comments
Thanks for the report. Note that the following works. //> using scala "3.1.3"
//> using lib "io.circe::circe-core::0.14.2"
//> using lib "io.circe::circe-parser::0.14.2"
import io.circe._
case class R1(int: Int, r: Seq[R1]) derives Encoder.AsObject
case class R2(int: Int, r: Option[R2]) derives Encoder.AsObject
@main def main =
summon[Encoder[R1]]
summon[Encoder[R2]] |
@armanbilge Yes, thanks for mentoning this workaround and sorry I forgot to 😃 I'm also looking for a different workaround as I'm not a big fan of mixing my precious data classes with 3rd party libraries - for the sake of domain purity. |
What is the "3rd party library" in this situation? |
Is this what you want? //> using scala "3.1.3"
//> using lib "io.circe::circe-core::0.14.2"
//> using lib "io.circe::circe-parser::0.14.2"
import io.circe._
case class R1(int: Int, r: Seq[R1])
case class R2(int: Int, r: Option[R2])
given Encoder.AsObject[R1] = Encoder.AsObject.derived
given Encoder.AsObject[R2] = Encoder.AsObject.derived
@main def main =
summon[Encoder[R1]]
summon[Encoder[R2]] |
Oh yes, this looks much better, thanks!!! 3rd party library in that case is circe. if I have a module that consists of only data classes, I prefer to have no dependencies and keep serialization/deserialization where it belongs (ex. router). |
And it seems that when a lib can use given Encoder.AsObject[R1] = AObject.derived It is not the privilege of circe. |
New findings, it's probably some "by-name" calls missing, because this doesn't work: using scala "3.2.1"
import scala.deriving.*
import scala.compiletime.{erasedValue, summonInline}
trait Show[A]:
def show(a: A): String
given Show[Int] with {
def show(a: Int): String = a.toString
}
inline def summonAll[T <: Tuple]: List[Show[_]] =
inline erasedValue[T] match
case _: EmptyTuple => Nil
case _: (t *: ts) => summonInline[Show[t]] :: summonAll[ts]
inline given Option[A](using inline s: Show[A]): Show[Option[A]] = new Show[Option[A]] {
override def show(a: Option[A]): String = a.map(s.show).getOrElse("")
}
inline given[A] (using m: Mirror.Of[A]): Show[A] = new Show[A] {
override def show(a: A): String = {
val elemInstances = summonAll[m.MirroredElemTypes]
elemInstances.mkString(", ")
}
}
case class Rec(int: Int, rs: Option[Rec])
object Main extends App {
summon[Show[Rec]]
} but this is ok: using scala "3.2.1"
import scala.deriving.*
import scala.compiletime.{erasedValue, summonInline}
trait Show[A]:
def show(a: A): String
given Show[Int] with {
def show(a: Int): String = a.toString
}
inline def summonAll[T <: Tuple]: List[Show[_]] =
inline erasedValue[T] match
case _: EmptyTuple => Nil
case _: (t *: ts) => summonInline[Show[t]] :: summonAll[ts]
inline given Option[A](using inline s: => Show[A]): Show[Option[A]] = new Show[Option[A]] {
override def show(a: Option[A]): String = a.map(s.show).getOrElse("")
}
inline given[A] (using m: Mirror.Of[A]): Show[A] = new Show[A] {
override def show(a: A): String = {
val elemInstances = summonAll[m.MirroredElemTypes]
elemInstances.mkString(", ")
}
}
case class Rec(int: Int, rs: Option[Rec])
object Main extends App {
summon[Show[Rec]]
} |
@hamnis I believe this is still an issue with 0.14.9 and Scala 3.4.2: //> using dep io.circe::circe-core:0.14.9
//> using dep io.circe::circe-generic:0.14.9
//> using dep io.circe::circe-parser:0.14.9
import io.circe._
import io.circe.generic.auto._
case class R1(int: Int, r: Seq[R1])
case class R2(int: Int, r: Option[R2])
summon[Encoder[R1]]
summon[Encoder[R2]] output:
|
Hi,
Both
summon
s fail but with slightly different messages:and
Probably related to scala/scala3#8183
The text was updated successfully, but these errors were encountered: