Skip to content
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

Stack overflow on 0.14.6 #2209

Open
GalLaloucheSqream opened this issue Oct 25, 2023 · 4 comments
Open

Stack overflow on 0.14.6 #2209

GalLaloucheSqream opened this issue Oct 25, 2023 · 4 comments
Labels

Comments

@GalLaloucheSqream
Copy link

GalLaloucheSqream commented Oct 25, 2023

Minimal reproduction steps:

import scala.annotation.tailrec
import io.circe.generic.auto._
import io.circe.syntax._

object CirceExample {
  case class Node(test: Vector[Node])
  @tailrec def go(maxSize: Int, result: Node): Node =
    if (maxSize == 0) result else go(maxSize - 1, Node(Vector(result)))
  def main(args: Array[String]): Unit =
    go(1000, Node(Vector.empty)).asJson: Unit
}

Running on Scala 2.13.10, and JDK 17.0.5.

@zarthross
Copy link
Member

What scala versions please?

@zarthross zarthross added the bug label Oct 25, 2023
@GalLaloucheSqream
Copy link
Author

What scala versions please?

I've updated the ticket with the Scala and Java version I've used.

@MartinHH
Copy link
Contributor

In Scala 3, the example code does not compile, but if one adds derives Codec.AsObject as follows, the behavior is the same (Stack Overflow):

//> using scala "3.3.1"
//> using jvm "17"

//> using dep "io.circe::circe-generic::0.14.6"

import scala.annotation.tailrec
import io.circe.generic.auto._
import io.circe.syntax._

object CirceExample {
  case class Node(test: Vector[Node]) derives io.circe.Codec.AsObject
  @tailrec def go(maxSize: Int, result: Node): Node =
    if (maxSize == 0) result else go(maxSize - 1, Node(Vector(result)))
  def main(args: Array[String]): Unit =
    go(1000, Node(Vector.empty)).asJson: Unit
}

(Furthermore: this is not specific to 0.14.6.)

@plokhotnyuk
Copy link
Contributor

plokhotnyuk commented Oct 28, 2023

@GalLaloucheSqream @MartinHH --java-opt -Xss4m should help for your samples

Even jsoniter-scala generates recursive calls for recursive data structures minimizing a stack depth to one call per one JSON level of nesting ({ or [).

A custom codec is required to transform recursive data structure into io.circe.Json using a heap-based stack and a while (tailrec) loop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants