Circe auto generic derivation causes diverging implicit expansion of `HlistToFunc`
zarthross opened this issue · 4 comments
I'll try and put in an example next week, but it appears the fix for #216 does break using circe's fully automatic derivation. In the mean time, the work around is just using the semiauto derivation instead.
The fix I currently have (which is of course unacceptable) :
import authContext._
import swaggerSyntax._
import io.circe.generic.auto._
import org.http4s.circe._
import org.http4s.rho.bits._
Importing in that order enables circe macros to work
Ok, actually I just got rid of all the errors by just extending CirceInstances at package level so I can now remove all these imports and just keep
import authContext._
import swaggerSyntax._
I see the same error (or a very similar one) when using semiauto derivation with circe-derivation
:
// build.sbt
scalaVersion := "2.12.8"
scalacOptions += "-Ypartial-unification"
libraryDependencies := Seq(
"io.circe" %% "circe-core" % "0.11.1",
"io.circe" %% "circe-derivation" % "0.11.0-M1",
"org.http4s" %% "http4s-circe" % "0.20.0-M6",
"org.http4s" %% "http4s-dsl" % "0.20.0-M6",
"org.http4s" %% "rho-swagger" % "0.19.0-M6",
"org.typelevel" %% "cats-effect" % "1.2.0"
)
// src/main/scala/Example.scala
import cats.effect.IO
import io.circe.Encoder
import io.circe.derivation.deriveEncoder
import org.http4s.circe.CirceEntityEncoder
import org.http4s.rho.RhoRoutes
object Example extends CirceEntityEncoder {
case class Response(a: String)
object Response {
implicit val encoder: Encoder[Response] = deriveEncoder
}
val routes = new RhoRoutes[IO] {
GET / "example" |>> { () =>
if (true) {
Ok(Response("foo"))
} else {
InternalServerError(Response("bar"))
}
}
}
}
As mentioned in #216 (comment), turning off partial unification gets things to compile, but that's not feasible in my full project. The two other workarounds I've found are:
- Explicitly call
.asJson
on each response. This fixes compilation, but leaves the model's info out of the eventually-generated Swagger documentation. - Copy-paste the derivation rule provided by
CirceEntityEncoder
, but with pinned type parameters:// This works import cats.effect.IO import io.circe.Encoder import io.circe.derivation.deriveEncoder import org.http4s.EntityEncoder import org.http4s.circe.CirceInstances import org.http4s.rho.RhoRoutes object Example extends CirceInstances { case class Response(a: String) object Response { implicit val encoder: Encoder[Response] = deriveEncoder } val routes = new RhoRoutes[IO] { GET / "example" |>> { () => implicit val e: EntityEncoder[IO, Response] = jsonEncoderOf[IO, Response] if (true) { Ok(Response("foo")) } else { InternalServerError(Response("bar")) } } } }
Currently I'm using solution 2. provided by @danxmoran and model is generating properly