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

Ambiguous Implicit values / Diverging implicit expansion #159

Closed
onlyNexusHere opened this issue Jun 15, 2016 · 13 comments
Closed

Ambiguous Implicit values / Diverging implicit expansion #159

onlyNexusHere opened this issue Jun 15, 2016 · 13 comments

Comments

@onlyNexusHere
Copy link

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.

@damienfir
Copy link

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

@danielyli
Copy link

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

@damienfir
Copy link

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.

@danielyli
Copy link

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

@192709
Copy link

192709 commented Oct 30, 2016

@danielyli : Did you find a workaround?

@ebruchez
Copy link

ebruchez commented Nov 1, 2016

I am hitting this error as well.

@danielyli
Copy link

@192709 No, I ended up using another library.

@192709
Copy link

192709 commented Nov 13, 2016

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

@ASchmidt84
Copy link

ASchmidt84 commented Dec 12, 2016

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.

@strelec
Copy link

strelec commented Apr 30, 2017

What is the progress on this?

@lihaoyi
Copy link
Member

lihaoyi commented May 1, 2017

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

@bmccutchon
Copy link

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.

@lihaoyi
Copy link
Member

lihaoyi commented Dec 19, 2017

Bug bankruptcy

@lihaoyi lihaoyi closed this as completed Dec 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants