ConfiguredJsonEncoder broken on upgrade from 0.8.0 to 0.9.1.
See original GitHub issueI’m attempting to upgrade a large enterprise Scala project from Circe 0.8.0 to 0.9.1 and getting a compiler error on the following code:
object Parsing {
// This is where the implicit `Configuration` comes from.
import JsonWithTypeField.implicits._
// Note: Circe needs empty companion objects after any extending case classes for all sealed traits below.
// This is to work around SI-7046 issues in a stable and repeatable way.
// See https://circe.github.io/circe/codec.html#warnings-and-known-issues, point 5, for more information.
@ConfiguredJsonCodec
sealed trait ValidationErrorHandling
object AttributeValidation {
@ConfiguredJsonCodec
sealed trait AttributeValidationErrorHandling extends ValidationErrorHandling
case object Strict extends AttributeValidationErrorHandling
case object EmptyAsDelete extends AttributeValidationErrorHandling
case object EmptyAndFailureAsDelete extends AttributeValidationErrorHandling
object AttributeValidationErrorHandling
}
object ActionValidation {
@ConfiguredJsonCodec
sealed trait ActionValidationErrorHandling extends ValidationErrorHandling
case object Strict extends ActionValidationErrorHandling
case object AllowEmpty extends ActionValidationErrorHandling
case object AllowEmptyAndFailure extends ActionValidationErrorHandling
object ActionValidationErrorHandling
}
object ValidationErrorHandling
// ...
}
This was compiling happily on circe 0.8.0 but fails to compile on circe 0.9.1:
[info] Compiling 29 Scala sources to [...]/target/scala-2.11/classes ...
[error] [...]/Parsing.scala:19:4: could not find Lazy implicit value of type io.circe.generic.extras.decoding.ConfiguredDecoder[com.foo.ValidationErrorHandling]
[error] @ConfiguredJsonCodec
[error] ^
[error] one error found
[error] (foo / Compile / compileIncremental) Compilation failed
[error] Total time: 18 s, completed 12-Mar-2018 16:12:12
After exhausting all the options of moving around wrapper object
types and ensuring I wasn’t being hit by the ghosts of SI-7046, I managed to track down that I could still have this example compile on 0.9.0-M2
but not 0.9.0-M3
- a quick git bisect
later revealed that the issue was introduced somewhere in the change at https://github.com/circe/circe/commit/5193b5b8bcc3910535d036f09adee259493c7cb8.
Unfortunately, I can’t seem to make a reproducible test case from just the above code. It’s worth noting that there are other decoders that reference these above too, I’m just posting the code snippet that actually fails compilation.
I’m not really able to say exactly what about this change causes the compilation in this project to fail, mainly because the commit in question is way over my head, but I’m happy to assist with reproducing the error in any way needed!
Issue Analytics
- State:
- Created 6 years ago
- Comments:7 (7 by maintainers)
Top GitHub Comments
This comment is a minimization for the sake of voting / discussion. The question is whether the following code should compile (I’m using
@JsonCodec
here, but you’d see the same thing with eitherauto
orsemiauto
):It doesn’t compile on 0.9.x, but does on 0.8 and earlier, where it has the following goofy behavior:
Specifically, Shapeless’s “union” doesn’t have unique keys, so either case object will get encoded in such a way that it will be decoded as the one whose wrapper object name is lexicographically first.
I’m inclined to think not compiling is the right thing to do here, since there are no other (known) cases where a generically derived encoder-decoder pair won’t round-trip values (at least for circe-generic), but I’m open to counter-arguments, or you can just vote:
👍: it should compile (the pre-0.9 behavior); 👎: it should not compile (the current behavior).
Ugh, that sounds plausible but unfortunate. Luckily we could fix it in 0.9.2 (which I’ve been meaning to release for the
validate
fix for the past few days, anyway).