Potential issue with deriving type classes that are already based on Mirrors
Hi,
I have a typeclass which is generated using Mirrors. There is a compilation failure returned when I use UnionDerivation on top of it.
Take a look at this minimal example:
//> using scala "3.5.2"
//> using lib "io.github.irevive::union-derivation-core:0.2.1"
//> using options "-Yretain-trees"
import scala.annotation.nowarn
import scala.deriving.Mirror
import io.github.irevive.union.derivation.IsUnion
import io.github.irevive.union.derivation.UnionDerivation
trait Show[A] {
def show(value: A): String
}
object Show {
inline given derivedUnion[A](using IsUnion[A]): Show[A] = UnionDerivation.derive[Show, A]
@nowarn("msg=New anonymous class definition will be duplicated at each inline site")
inline given instance[A](using m: Mirror.ProductOf[A]): Show[A] = {
println(s"$m") // if you remove it, then it compiles
new Show[A] {
def show(value: A): String = value.toString()
}
}
}
case class A(x: String)
case class B(y: Int)
// it also compiles when you uncomment those:
// given Show[A] = Show.instance[A]
// given Show[B] = Show.instance[B]
@main def hello() = println(Show.derivedUnion[A | B].show(A("1")))
It returns
Error: Error while emitting example.scala
val m$proxy1
The error goes away if you either don't use the mirror (even if you declare it in using clause) or if you generate the instances outside of UnionDerivation macro.
This change made the snippet compile:
- inline given instance[A](using m: Mirror.ProductOf[A]): Show[A] = {
+ inline given instance[A](using inline m: Mirror.ProductOf[A]): Show[A] = {
It may be a non-trivial compiler issue, but I didn't dive into it, to be honest.
Since 3.3.0 it is going to fail https://github.com/scala/scala3/issues/16804 when you use anything from this inlined param (like m.MirroredElemLabels) - see this for context.
(m : scala.deriving.Mirror.ProductOf[A]) is not a valid type prefix, since it is not an immutable path
[error] |Inline parameters are not considered immutable paths and cannot be used as
[error] |singleton types.
[error] |
[error] |Hint: Removing the `inline` qualifier from the `m` parameter
[error] |may help resolve this issue.
I can see that they witnessed issues with it in circe - https://github.com/circe/circe/pull/2287 / https://github.com/circe/circe/pull/2278