amnaredo / test

0 stars 0 forks source link

Implicit R/W expansion fails for covariant types #99

Open amnaredo opened 3 years ago

amnaredo commented 3 years ago

It turned out to be a covariance problem, this doesn't resolve implicits :

import upickle.Aliases.R
object Main extends App {
  trait Request[+O]
  case class Append[O: R](storeName: String) extends Request[O]
  val append: Request[Int] = Append("play")
}

diverging implicit expansion for type upickle.Aliases.R[O] [error] starting with macro method macroR in object Reader [error] val append: Request[Int] = Append("play")

This is OK:

import upickle.Aliases.R
object Main extends App {
  trait Request[O]
  case class Append[O: R](storeName: String) extends Request[O]
  val append: Request[Int] = Append("play")
}

ID: 51 Original Author: l15k4

amnaredo commented 3 years ago

To summarize the problem, combination of covariance and type inference leads to R/W implicit resolution fail. I tried to reproduce it with other kinds of sample type classes, but it works with them it is uPickle specific...

I need covariant types especially for Nothing values.

Original Author: l15k4

amnaredo commented 3 years ago

Yes, I've seen this problem before as well. In particular this can be pickled

case class Tree[T](value: T, children: Vector[Tree[T]])

But this doesn't

case class Tree[+T](value: T, children: Vector[Tree[T]])

Even though it really should. If anyone wants to pick this up and send a PR, please do ^_^ otherwise I'll get to it eventually

Original Author: lihaoyi

amnaredo commented 3 years ago

I've fixed my use case, which needed more type annotations inside the generated code. @l15k4 I don't think your use case is fixable at all. e.g. this fails too

  trait Request[+O]
  case class Append[O: Ordering](storeName: String) extends Request[O]
  val append: Request[Int] = Append("play")

Completely independant of uPickle. It's just the way Scala is =/ which isn't great, but out of my control. You'll just have to annotate your types more

  trait Request[+O]
  case class Append[O: Ordering](storeName: String) extends Request[O]
  val append = Append[Int]("play")

Original Author: lihaoyi