amnaredo / test

0 stars 0 forks source link

Ambiguous Implicit values / Diverging implicit expansion #177

Open amnaredo opened 3 years ago

amnaredo commented 3 years ago

uPickle unable to parse through this code:

import upickle.default._
type Env = Map[String,V]
object Simple {

  type Var = String

  sealed trait Expr      //will be evaluated into V
  case class ENum(n: Double) extends Expr
  case class EVar(name: String) extends Expr
  case class EOp(op: String, es: Seq[Expr]) extends Expr
  case class EFun(formal: String, body: Expr) extends Expr
  case class EApp(fun: Expr, actual: Expr) extends Expr

  sealed trait V           //cannot be evaluated further
  case class VNum(n: Double) extends V
  case class VClosure(x: String, body: Expr, t: Map[String, V]) extends V

  sealed trait VorE     //a wrapped that excepts either Expr or V
  case class Vo(v: V) extends VorE
  case class Eo(e: Expr) extends VorE

  type Stack = List[K]

  sealed trait K     //Stack items. Exprs and variables are turned into stack items when placed on stack.
  case class KArg(e: Expr) extends K
  case class KClosure(formal: String, body: Expr, t: Map[String,V]) extends K
  case class KOp(op: String, env: Map[String,V], vals: List[V], exprs: Seq[Expr]) extends K

              // These lines compile
// def writeState(state: (List[K], Env, VorE)): String = write(state)
//   def readState(str: String): (List[K], Env, VorE) = read[(List[K], Env, VorE)](str)

           // These lines do not compile
//   def writeKClos(trial: KClosure) : String = write(trial)
//   def readKClos(str: String): KClosure = read[KClosure](str)

          // These lines do not compile.
  def write3Tuple(n: (String, Expr, Map[String, V])): String = write[(String, Expr, Map[String, V])](n)
  def read3Tuple(str: String): (String, Expr, Map[String, V]) = read[(String, Expr, Map[String, V])](str)
}

With exactly this code, I get this error message:

[info] Compiling 2 Scala sources... [error] Line 37: ambiguous implicit values: [error] both value derive$macro$249 of type => upickle.default.Writer[(String, Simple.Expr, Map[String,Simple.V])] [error] and value derive$macro$266 of type => upickle.default.Writer[Simple.EOp] [error] match expected type upickle.default.Writer[T1] [error] Error occurred in an application involving default arguments. [error] def write3Tuple(n: (String, Expr, Map[String, V])): String = write(String, Expr, Map[String, V]) [error] ^ [error] Line 38: ambiguous implicit values: [error] both value derive$macro$588 of type => upickle.default.Reader[(String, Simple.Expr, Map[String,Simple.V])] [error] and value derive$macro$605 of type => upickle.default.Reader[Simple.EOp] [error] match expected type upickle.default.Reader[T1] [error] def read3Tuple(str: String): (String, Expr, Map[String, V]) = read(String, Expr, Map[String, V]) [error] ^ [error] two errors found error Compilation failed [error] Total time: 8 s, completed Jun 15, 2016 1:44:19 PM

With the def writeKClos and def readKClos uncommented and the last two lines commented, I get:

compile [info] Compiling 2 Scala sources... [error]Line 34: diverging implicit expansion for type upickle.default.Writer[T1] [error] starting with macro method macroW in trait LowPriX [error] Error occurred in an application involving default arguments. [error] def writeKClos(trial: KClosure) : String = write(trial) [error] ^ [error]Line 35: diverging implicit expansion for type upickle.default.Reader[T1] [error] starting with macro method macroR in trait LowPriX [error] def readKClos(str: String): KClosure = readKClosure [error] ^ [error] two errors found error Compilation failed [error] Total time: 11 s, completed Jun 15, 2016 1:54:23 PM

When def writeState and def readState are not commented and all following lines are commented, the code compiles fine.

I am not sure what diverging implicit expansion means in terms of how my project is laid out. However, everything that is included in the file should compile file. It does not, and I have no idea why.

Notes: This is all done with sbt on a Mac. Nothing in the project is imported, and no other file uses this file. This is not quite what I was using in the project, but this is the simplest example where the behavior shows.

ID: 159 Original Author: onlyNexusHere

amnaredo commented 3 years ago

I can reproduce a similar issue with the following code using Autowire and uPickle in Play:

import upickle.default._
import upickle.Js

object AutowireServer extends autowire.Server[Js.Value, Reader, Writer] {
  override def write[R: Writer](r: R) = writeJs(r)
  override def read[R: Reader](s: Js.Value) = readJs[R](s)
}

class Application extends Controller {
  def autowireApi(path: String) = Action.async(parse.tolerantText) {
    implicit request =>

      AutowireServer.route[Api](serverApi) {
        autowire.Core.Request(path.split("/"), json.read(request.body).asInstanceOf[Js.Obj].value.toMap)
      }
      .map(s => Ok(json.write(s)))
  }
}
server/app/controllers/Application.scala:47: diverging implicit expansion for type upickle.default.Writer[T1]
[error] starting with macro method macroW in trait LowPriX
[error]       AutowireServer.route[Api](serverApi) {
[error]                                ^
[error] one error found
[error] (server/compile:compileIncremental) Compilation failed

I am using uPickle 0.4.1, Scala 2.11.7 and Play 2.4.6

Original Author: damienfir

amnaredo commented 3 years ago

@damienfir @onlyNexusHere Have either of you found workarounds? I'm experiencing the same problem, and it's a major blocker.

Original Author: danielyli

amnaredo commented 3 years ago

Yes I found a workaround. I was trying to use uPickle on a case class extending a trait and it gave me the error. Replacing the trait by a sealed trait solved the problem.

Original Author: damienfir

amnaredo commented 3 years ago

Thanks for letting me know. Unfortunately, I'm already using sealed everywhere, so that isn't the problem. I'll keep hunting...

Original Author: danielyli

amnaredo commented 3 years ago

@danielyli : Did you find a workaround?

Original Author: 192709

amnaredo commented 3 years ago

I am hitting this error as well.

Original Author: ebruchez

amnaredo commented 3 years ago

@192709 No, I ended up using another library.

Original Author: danielyli

amnaredo commented 3 years ago

@danielyli: Thank you for your reply. I read http://www.gitterforum.com/discussion/lihaoyi-upickle-pprint?page=23 and could bring it to work.

Original Author: 192709

amnaredo commented 3 years ago

Hi, had the same issue. def autowireAjax(path: String) = Action.async[String](parse.text) { request => val e: String = request.body val f: Future[String] = AutoWireServer.route[SharedApi](this)(autowire.Core.Request( path.split('/'), upickle.json.read(e).asInstanceOf[Js.Obj].value.toMap) ).map(upickle.json.write(_,2)) val fr: Future[Result] = f.map { s => Ok(s) } fr } I tried to change to this def autowireAjax(path: String) = Action.async[String](parse.tolerantText) { request => val e: String = request.body val f: Future[String] = AutoWireServer.route[SharedApi](this)(autowire.Core.Request( path.split('/'), upickle.json.read(e).asInstanceOf[Js.Obj].value.toMap) ).map(upickle.json.write(_,2)) val fr: Future[Result] = f.map { s => Ok(s) } fr } and this worked. Original Author: ASchmidt84

amnaredo commented 3 years ago

What is the progress on this? Original Author: strelec

amnaredo commented 3 years ago

If you want me to have time to look at this, chip in https://www.patreon.com/lihaoyi Original Author: lihaoyi

amnaredo commented 3 years ago

This happened to me when I changed a sealed trait to a sealed class, call it X. If I try to serialize a case class with a field X, I get the implicits error. If I try to serialize an instance of X, I get a "Couldn't derive type X" error. This unfortunately didn't help (though it might help someone else). I worked around it by keeping it as a trait and using an abstract method instead of a field. Original Author: bmccutchon

amnaredo commented 3 years ago

Bug bankruptcy Original Author: lihaoyi