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

Circe auto generic derivation causes diverging implicit expansion of HlistToFunc #292

Open
zarthross opened this issue Feb 21, 2019 · 4 comments
Labels

Comments

@zarthross
Copy link
Member

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.

@Igosuki
Copy link
Contributor

Igosuki commented Feb 22, 2019

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

@Igosuki
Copy link
Contributor

Igosuki commented Feb 22, 2019

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._

@danxmoran
Copy link
Contributor

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:

  1. Explicitly call .asJson on each response. This fixes compilation, but leaves the model's info out of the eventually-generated Swagger documentation.
  2. 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"))
          }
        }
      }
    }

@PawelJ-PL
Copy link

Currently I'm using solution 2. provided by @danxmoran and model is generating properly

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