softwaremill/diffx

StackOverflowException during coproduct derivation when using semi-auto

ghostbuster91 opened this issue · 0 comments

Given following coproduct

sealed trait ACoproduct extends Product with Serializable
object ACoproduct {
  case class ProductA(id: String) extends ACoproduct
  case class ProductB(id: String) extends ACoproduct
}

when defining diff instance for such coproduct inside method:

  "should work for coproducts" in {
    implicit val dACoproduct: Diff[ACoproduct] = Diff.derived[ACoproduct]

    Diff[ACoproduct].apply(ProductA("1"), ProductA("1")) shouldBe Identical(ProductA("1"))
  }

Compilation fails with the following message:

DiffSemiautoTest.scala:43:62: forward reference extends over definition of value dACoproduct
[error]     implicit val dACoproduct: Diff[ACoproduct] = Diff.derived[ACoproduct]

Moving instance definition to the class level fixes the compilation but causes Stackoverflow exception in runtime:

[info] com.softwaremill.diffx.test.DiffSemiautoTest *** ABORTED ***
[info]   java.lang.StackOverflowError:
[info]   at magnolia.SealedTrait.rec$1(interface.scala:403)
[info]   at magnolia.SealedTrait.dispatch(interface.scala:408)
[info]   at com.softwaremill.diffx.generic.DiffMagnoliaDerivation.com$softwaremill$diffx$generic$DiffMagnoliaDerivation$$$anonfun$dispatch$1(DiffMagnoliaDerivation.scala:31)

Wrapping both the instance and the result type with the Derived class fixes that problem in both cases:

implicit val dACoproduct: Derived[Diff[ACoproduct]] = Derived(Diff.derived[ACoproduct])

but it doesn't seem that it should work like that.