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

Reimplement the Scala 3 schema derivation without Mirror #395

Closed
vigoo opened this issue Oct 28, 2022 · 0 comments
Closed

Reimplement the Scala 3 schema derivation without Mirror #395

vigoo opened this issue Oct 28, 2022 · 0 comments

Comments

@vigoo
Copy link
Contributor

vigoo commented Oct 28, 2022

Original problem:

The following does not work:

object T {
   implicit val schema: Schema[T] = DeriveSchema.gen
   val (...) = makeAccessors[T]
}

def makeAcessors[T](implicit schema: Schema[T]) = schema.makeAccessors(customAccessorBuilder)

while if we let the compiler to use the type generated by DeriveSchema it does:

object T {
   implicit val schema = DeriveSchema.gen[T]
   val (...) = makeAccessors[T]
}

The problem is that Scala 3 does not compile this, requiring all implicits to have explicit type annotation (which is the first version).

We could do the following trick to work around this:

object T {
   val generatedSchema = DeriveSchema.gen[T]
   implicit val schema: generatedSchema.type = generatedSchema
   val (...) = makeAccessors[T]
}

and this compiles on Scala 2, but it creates cyclic reference on Scala 3.

The reason for that is that summon is called before checking whether we are on top level and that is easy to fix:

            val summoned = if (!top) Expr.summon[Schema[T]] else None
            summoned match {
              case Some(schema) =>

instead of

            Expr.summon[Schema[T]] match {
              case Some(schema) if !top =>

but that still does not work because Mirror(typeRepr) returnsNone for a type like that (I guess it is also trying to summon the implicit for T under the hood).

If the macro does not get the Mirror (just generates null for example) then the code with the above workaround compiles on Scala 3, so I believe a derive macro that does not rely on Mirror would solve this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

No branches or pull requests

1 participant