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

Recurrent args hang in compile time or runtime #407

Closed
pawelprazak opened this issue Feb 28, 2024 · 1 comment
Closed

Recurrent args hang in compile time or runtime #407

pawelprazak opened this issue Feb 28, 2024 · 1 comment
Assignees
Labels
area/core The SDK's core code kind/bug Some behavior is incorrect or out of spec P1 Bugs severe enough to be the next item assigned to an engineer
Milestone

Comments

@pawelprazak
Copy link
Contributor

This test replicated a problem detected in JsonSchemaPropsArgs (k8s)

class RecurrentArgsTest extends munit.FunSuite with ValueAssertions:
  case class Recurrent (
    properties: Option[Recurrent]
  )
  object Recurrent:
    given encoder(using besom.types.Context): besom.types.Encoder[Recurrent] =
      besom.internal.Encoder.derived[Recurrent]
      
  test("encode recurrent type") {
    given Context = DummyContext().unsafeRunSync()
    val e         = summon[Encoder[Recurrent]]

    val (_, encoded) = e.encode(Recurrent(Some(Recurrent(Some(Recurrent(Some(Recurrent(None)))))))).unsafeRunSync()

    val expected =
      Map("value" -> Map("value" -> Map("value" -> Map("value" -> Map("value" -> Map().asValue).asValue).asValue).asValue).asValue).asValue
    assertEqualsValue(encoded, expected)
  }
end RecurrentArgsTest

This results in a stack overflow:

besom.internal.RecurrentArgsTest:
==> X besom.internal.RecurrentArgsTest.encode recurrent type  0.033s java.lang.StackOverflowError: null
    at scala.collection.immutable.List.prependedAll(List.scala:148)
    at scala.collection.immutable.List$.from(List.scala:684)
    at scala.collection.immutable.List$.from(List.scala:681)
    at scala.collection.IterableFactory.apply(Factory.scala:103)
    at scala.collection.IterableFactory.apply$(Factory.scala:103)
    at scala.collection.immutable.List$.apply(List.scala:681)
    at besom.internal.RecurrentArgsTest.labels$lzyINIT17$1(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest.besom$internal$RecurrentArgsTest$Recurrent$$$_$labels$17(EncoderTest.scala:477)
    at besom.internal.RecurrentArgsTest$Recurrent$.nameEncoderPairs$lzyINIT17$1(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.nameEncoderPairs$17(EncoderTest.scala:477)
    at besom.internal.RecurrentArgsTest$Recurrent$.encoder(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.instances$lzyINIT17$1(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.instances$17(EncoderTest.scala:477)
    at besom.internal.RecurrentArgsTest$Recurrent$.nameEncoderPairs$lzyINIT17$1(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.nameEncoderPairs$17(EncoderTest.scala:477)
    at besom.internal.RecurrentArgsTest$Recurrent$.encoder(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.instances$lzyINIT17$1(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.instances$17(EncoderTest.scala:477)
    at besom.internal.RecurrentArgsTest$Recurrent$.nameEncoderPairs$lzyINIT17$1(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.nameEncoderPairs$17(EncoderTest.scala:477)
    at besom.internal.RecurrentArgsTest$Recurrent$.encoder(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.instances$lzyINIT17$1(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.instances$17(EncoderTest.scala:477)
    at besom.internal.RecurrentArgsTest$Recurrent$.nameEncoderPairs$lzyINIT17$1(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.nameEncoderPairs$17(EncoderTest.scala:477)
    at besom.internal.RecurrentArgsTest$Recurrent$.encoder(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.instances$lzyINIT17$1(EncoderTest.scala:464)
    at besom.internal.RecurrentArgsTest$Recurrent$.instances$17(EncoderTest.scala:477)
    at besom.internal.RecurrentArgsTest$Recurrent$.nameEncoderPairs$lzyINIT17$1(EncoderTest.scala:464)
    ...

Two interesting variants:

  1. adding union causes the test to pass
case class Recurrent(value: Recurrent | Option[Recurrent])
  1. using derives instead of derived results in a compile time hang.
@pawelprazak pawelprazak added kind/bug Some behavior is incorrect or out of spec area/core The SDK's core code P1 Bugs severe enough to be the next item assigned to an engineer labels Feb 28, 2024
@pawelprazak pawelprazak added this to the 0.2.3 milestone Feb 28, 2024
@lbialy
Copy link
Collaborator

lbialy commented Feb 28, 2024

fixed by these changes in codecs.scala

 // here: change to by-name parameter
  def encoderSum[A](mirror: Mirror.SumOf[A], nameEncoderPairs: => List[(String, Encoder[?])]): Encoder[A] = ...

  // here: change to by-name parameter
  def encoderProduct[A](nameEncoderPairs: => List[(String, Encoder[?])]): Encoder[A] = ...

@pawelprazak pawelprazak modified the milestones: 0.2.3, 0.2.4 Feb 28, 2024
@pawelprazak pawelprazak modified the milestones: 0.2.4, 0.3.0 Mar 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/core The SDK's core code kind/bug Some behavior is incorrect or out of spec P1 Bugs severe enough to be the next item assigned to an engineer
Projects
None yet
Development

No branches or pull requests

2 participants