Possible derivation regression since shapeless 2.3.8
pomadchin opened this issue · comments
The shapeless 2.3.8 dependency update caused frameless test compilation failure, you can find the PR and the CI failure here: typelevel/frameless#612
I decided to go investigate it a little and to prepare a scoped example of the code that causes compilation errors, it looks like it may be related to the type alias
resolution and Generic
derivation:
Code example, function fooPrintT compiles with Shapeless <= 2.3.7 but not with 2.3.8
import shapeless.{Generic, HList, HNil, ::}
trait TC[A] { def foo: A }
object TC {
def apply[A](implicit ev: TC[A]): TC[A] = ev
implicit val booleanTC = new TC[Boolean] { def foo: Boolean = true }
implicit val intTC = new TC[Int] { def foo: Int = 42 }
implicit val longTC = new TC[Long] { def foo: Long = 420L }
implicit def genericTC[T, L <: HList](implicit gen: Generic.Aux[T, L], tc: TC[L]): TC[T] = new TC[T] { def foo: T = gen.from(tc.foo) }
implicit def tcHNil: TC[HNil] = new TC[HNil] { def foo: HNil = HNil }
implicit def tcHCons[H, T <: HList](implicit dh: TC[H], dt: TC[T]): TC[H :: T] = new TC[H :: T] { def foo: H :: T = dh.foo :: dt.foo }
}
case class TX2[A, B](a: A, b: B)
case class TX3[A, B, C](a: A, b: B, c: C)
def fooPrint[A: TC, B: TC](data: TX2[A, B]): Unit = println(TC[TX2[A, B]].foo)
fooPrint(TX2[Int, Boolean](1, true))
type TTX3[A, B] = TX3[Long, Int, TX2[A, B]]
// compiles with shapeless <= 2.3.7
def fooPrintT[A: TC, B: TC](data: TTX3[A, B]): Unit = println(TC[TTX3[A, B]].foo)
fooPrintT(TX3(1L, 1, TX2(1, true)))
build.sbt
libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.8"
scalaVersion := "2.13.8"
Compilation error
could not find implicit value for parameter ev: TC[TTX3[A,B]]
[error] def fooPrintT[A: TC, B: TC](data: TTX3[A, B]): Unit = println(TC[TTX3[A, B]].foo)
Scastie (downgrade shapeless to see that compilation works)
https://scastie.scala-lang.org/pomadchin/Q8XBuPBVTTajvomVe3YZfQ/5
I tried to narrow the example more:
import shapeless.{Generic, HList}
case class TX2[A, B](a: A, b: B)
case class TX3[A, B, C](a: A, b: B, c: C)
def tx2[A, B](data: TX2[A, B])(implicit g: Generic[TX2[A, B]]): Unit = {}
tx2(TX2[Int, Boolean](1, true))
type TTX3[A, B] = TX3[Long, Int, TX2[A, B]]
def tx3[A, B](data: TTX3[A, B])(implicit g: Generic[TTX3[A, B]]): Unit = {}
// compiles with shapeless <= 2.3.7
// could be fixed for 2.3.8 by removing the type alias
// def tx3[A, B](data: TTX3[A, B])(implicit g: Generic[TX3[Long, Int, TX2[A, B]]]): Unit = {}
tx3(TX3(1L, 1, TX2(1, true)))
Scastie: https://scastie.scala-lang.org/pomadchin/D46I0pY3TuegOXIqicrZkg/9
Thanks for the report. We might be missing a dealias
call somewhere and it shouldn't be too hard by looking at the commits between 2.3.7 and 2.3.8