Skip to content

given instance is declared as erased, but is in fact used #13044

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
ghostdogpr opened this issue Jul 11, 2021 · 11 comments · Fixed by #13783
Closed

given instance is declared as erased, but is in fact used #13044

ghostdogpr opened this issue Jul 11, 2021 · 11 comments · Fixed by #13783
Labels
area:inline itype:bug Spree Suitable for a future Spree
Milestone

Comments

@ghostdogpr
Copy link
Contributor

ghostdogpr commented Jul 11, 2021

Compiler version

3.0.1

Minimized code

import scala.deriving.Mirror
import scala.compiletime._

trait Schema[T] {
  def build: T
}

object Schema extends SchemaDerivation {
  implicit lazy val int: Schema[Int]   = ???
  implicit def option[A](implicit ev: Schema[A]): Schema[Option[A]] = ???
}

trait SchemaDerivation {
  inline def recurse[A <: Tuple]: List[Schema[Any]] =
    inline erasedValue[A] match {
      case _: (t *: ts) =>
        val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]]
        builder :: recurse[ts]
      case _: EmptyTuple => Nil
    }

  inline def derived[A]: Schema[A] =
    inline summonInline[Mirror.Of[A]] match {
      case m: Mirror.SumOf[A] =>
        lazy val subTypes = recurse[m.MirroredElemTypes]
        new Schema[A] {
          def build: A = ???
        }

      case m: Mirror.ProductOf[A] =>
        lazy val fields = recurse[m.MirroredElemTypes]
        new Schema[A] {
          def build: A = ???
        }
    }

  inline given gen[A]: Schema[A] = derived
}

case class H(i: Int)
case class G(h: H)
case class F(g: G)
case class E(f: Option[F])
case class D(e: E)
case class C(d: D)
case class B(c: C)
case class A(a: Option[A], b: B)

object TestApp {
  @main def test = {
    implicit lazy val typeSchema: Schema[A] = Schema.gen
  }
}

Output

given instance gen is declared as erased, but is in fact used
method recurse is declared as erased, but is in fact used

Expectation

I got this error while upgrading caliban from 3.0.0 to 3.0.1 on some code that was previously compiling. It seems that it fails to derive a typeclass instance in the presence of recursion and nesting. If I reduce the nesting, it works. I managed to reproduce it with the smaller example above, but this code fails with 3.0.0 with a different error. Any idea what's going on?

@griggt
Copy link
Contributor

griggt commented Jul 12, 2021

FWIW, the example compiles for me on both 3.0.0 and 3.0.1 with -Xmax-inlines 33 (the default is 32)

@ghostdogpr
Copy link
Contributor Author

FWIW, the example compiles for me on both 3.0.0 and 3.0.1 with -Xmax-inlines 33 (the default is 32)

Oh, I was not aware of this setting, I confirm it solves my initial problem 👍
Maybe the error message could be more explicit?

@anatoliykmetyuk anatoliykmetyuk added the stat:needs minimization Needs a self contained minimization label Jul 13, 2021
@odersky odersky added the area:reporting Error reporting including formatting, implicit suggestions, etc label Jul 13, 2021
@joroKr21
Copy link
Member

Is this a new option? The same code that compiled without it on Scala 3.0.0 now requires increasing this value on Scala 3.0.1: typelevel/kittens#376 Also a bit annoying for build.sbt that we can't use -Xmax-inlines:33 or -Xmax-inlines=33 😄

@dwijnand
Copy link
Member

Also a bit annoying for build.sbt that we can't use -Xmax-inlines:33 or -Xmax-inlines=33

Coming in 3.1.0: #13267

@nicolasstucki
Copy link
Contributor

It seems we are missing not inlining one of the calls to Schema.{gen, recurse}. This then fails with an error that mentions the erased nature of inline methods. This should wither inline during the inlining phase or fail with an error at that phase. It should not reach the erasure phase.

@nicolasstucki nicolasstucki added area:inline and removed area:reporting Error reporting including formatting, implicit suggestions, etc labels Aug 30, 2021
@anatoliykmetyuk anatoliykmetyuk added the Spree Suitable for a future Spree label Oct 15, 2021
@ghostdogpr
Copy link
Contributor Author

I had this error come up in a new place when I upgraded from 3.0.2 to 3.1.0 (similar derivation for very nested and recursive code). Increasing -Xmax-inlines didn't solve it this time, the compilation seemed to never end.

@nicolasstucki nicolasstucki removed the stat:needs minimization Needs a self contained minimization label Oct 21, 2021
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Oct 21, 2021
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Oct 21, 2021
@nicolasstucki
Copy link
Contributor

@ghostdogpr if -Xmax-inlines does not solve the issue this time, then it seems to be another issue. Could you open a new issue with the code that fails?

@ghostdogpr
Copy link
Contributor Author

@nicolasstucki I have a hard time reproducing it in an isolated minimized way. Is it okay if I provide an entire repo?

@nicolasstucki
Copy link
Contributor

Yes, we will mark it as needs-minimization. Just make sure to refer to a branch that will not change until the issue is fixed.

@ghostdogpr
Copy link
Contributor Author

Opened #13785 👍

@adamw
Copy link
Contributor

adamw commented Jan 25, 2022

We've hit this problem in tapir (softwaremill/tapir#1731), and minimized a bit in magnolia (softwaremill/magnolia#374). While bumping the max-inline does solve the problem, I think it's not really resolved - we either have to come up with a better solution in magnolia (suggestions welcome :) - one idea we have is to replace depending on Mirrors with macros, but if at all, this might only reduce the inlining height, not eliminate it completely) or maybe bump the limit in Scala?

The case classes involved aren't that complicated, so I suspect this might surface once and again when using typeclass derivation (esp using Magnolia) in real-world scenarios, which get much more complex.

Finally, the error is quite misleading. Maybe it would make sense to open another issue to make this more actionable (sth like "Max-inline limit reach. Increase using max-inlines to continue"? Would that be technically possible to detect?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
area:inline itype:bug Spree Suitable for a future Spree
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants