Skip to content

Typeclass derivation fails with no useful information #18166

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

Open
pmeheut opened this issue Jul 7, 2023 · 9 comments
Open

Typeclass derivation fails with no useful information #18166

pmeheut opened this issue Jul 7, 2023 · 9 comments
Labels
area:inline area:reporting Error reporting including formatting, implicit suggestions, etc area:typeclass-derivation itype:enhancement

Comments

@pmeheut
Copy link

pmeheut commented Jul 7, 2023

With caliban 2.0.0, the code compiles and works. With 2.2.0, it fails and the recursive error message is not helpful at all.

Compiler version

3.3.0

Minimized example

import caliban.client.*
import sttp.client3.*
import sttp.client3.circe.*
import sttp.model.*
import io.circe.*
import io.circe.parser.*
import io.circe.syntax.*
import io.circe.generic.auto.*
import io.circe.parser.decode

class Foo {
    val foo = implicitly[BodySerializer[GraphQLRequest]]
}

build.sbt

ThisBuild / scalaVersion := "3.3.0"

lazy val root = (project in file("."))
  .settings(
    name := "scala_bug_2",
    libraryDependencies ++= Seq("com.github.ghostdogpr" %% "caliban-client" % "2.2.0",
      "com.softwaremill.sttp.client3" %% "core" % "3.8.3",
      "com.softwaremill.sttp.client3" %% "circe" % "3.8.3",
      "com.softwaremill.sttp.client3" %% "zio" % "3.8.3",
      "io.circe" %% "circe-generic" % "0.14.3",
      "io.circe" %% "circe-parser" % "0.14.3")
  )

``
## Output

```scala
[error] 12 |    val foo = implicitly[BodySerializer[GraphQLRequest]]
[error]    |                                                        ^
[error]    |             method derived is declared as `inline`, but was not inlined
[error]    |
[error]    |             Try increasing `-Xmax-inlines` above 32
[error]    |----------------------------------------------------------------------------
[error]    |Inline stack trace
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Derivation.scala:16
[error]     ----------------------------------------------------------------------------
[error] one error found

Expectation

At least an usable error message pointed out the source of the problem in the code because increasing -Xmax-inlines has no effect.

@pmeheut pmeheut added the stat:needs triage Every issue needs to have an "area" and "itype" label label Jul 7, 2023
@WojciechMazur
Copy link
Contributor

Open CB failures of zio/zio-config might be related to that.
It fails with same error in 3.3.1-RC3: https://github.com/VirtusLab/community-build3/actions/runs/5480083582/jobs/9985438703
However, it compiles in 3.3.2-RC1 Nightly, but fails with different error https://github.com/VirtusLab/community-build3/actions/runs/5426571795/jobs/9871306636

@WojciechMazur
Copy link
Contributor

WojciechMazur commented Jul 7, 2023

I think it might be rather a regression in one of used libraries, if I need to guess, then I'd bet on import io.circe.generic.auto.* which might generate a new typeclass for each found usage of given type

And if fact it matches a source code for that version: https://github.com/circe/circe/blob/505fa69c73306ce98b67f4d224799774a5ba3e67/modules/core/shared/src/main/scala-3/io/circe/Derivation.scala#L16-L17

What's interesting this Derivation is deprecated since 0.14.4, so they're probably aware of this kind of issues, however the given snippet would still fail to compile even when using latest versions of libraries. There no version of Scala 3 in which it would successfully compile

@smarter smarter added area:reporting Error reporting including formatting, implicit suggestions, etc area:inline area:typeclass-derivation itype:enhancement and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jul 7, 2023
@smarter
Copy link
Member

smarter commented Jul 7, 2023

I believe the relevant circe issue is circe/circe#2126, I'm not sure if there's actually something we can do differently in the compiler since we don't know what the inline def is trying to achieve in general so it's hard for us to give more precise error messages. perhaps we could let the authors of the inline def customize the error that is reported in cases like this, but full auto derivation is just the wrong default in circe.

@pmeheut
Copy link
Author

pmeheut commented Jul 7, 2023

Thanks. Now I understand. Because Caliban 2.2.0 moved from Circe to jsoniter, GraphQLRequest and other classes do not provide the implicit Circe encoders/decoders anymore.
So the compiler tries full auto-derivation and fails.

This is not obvious.

@odersky
Copy link
Contributor

odersky commented Jul 8, 2023

It's not the compiler that tries that, it's the type class derivation macro library that circe uses (kitten, maybe?). Once we move to Scala 3 built in typeclass derivation, it will be up the the compiler. And hopefully that will be more predictable..

@smarter
Copy link
Member

smarter commented Jul 8, 2023

, it's the type class derivation macro library that circe uses (kitten, maybe?).

circe implements typeclass derivation for scala 3 by itself via inline defs: https://github.com/circe/circe/blob/series/0.14.x/modules/core/shared/src/main/scala-3/io/circe/derivation/package.scala

Once we move to Scala 3 built in typeclass derivation, it will be up the the compiler.

Is this referring to an upcoming feature?

@odersky
Copy link
Contributor

odersky commented Jul 8, 2023

Ah indeed. Not sure why it tried to call itself in a cycle then.

@bishabosha
Copy link
Member

bishabosha commented Jul 8, 2023

What is the definition ofGraphQLRequest ? - edit: I found it and i dont that is relevant to this issue

@bishabosha
Copy link
Member

bishabosha commented Jul 8, 2023

You can also try -Xprint:inlining to try and see the trees that get inlined

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:inline area:reporting Error reporting including formatting, implicit suggestions, etc area:typeclass-derivation itype:enhancement
Projects
None yet
Development

No branches or pull requests

5 participants