Skip to content

Commit

Permalink
don't use weakTypeOf[existential], fixes com-lihaoyi#116
Browse files Browse the repository at this point in the history
The reason is that an existential type (a higher-kinded type seems to be modeled
as an existential) closes over its environment, so that its reification closes
over the macro implementation which leads to compilation complications.

See scalamacros/paradise#68 for more information
about the general issue.
  • Loading branch information
jrudolph committed Nov 2, 2015
1 parent 38c8ad3 commit 3783013
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 27 deletions.
23 changes: 4 additions & 19 deletions derive/shared/src/main/scala/derive/Derive.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import language.higherKinds
* default string which is the full-name of that class/field.
*/
class key(s: String) extends StaticAnnotation
trait DeriveApi[M[_]]{
trait DeriveApi{
val c: Context
import c.universe._
def typeclass: c.WeakTypeTag[M[_]]
def typeclassFor[T: c.WeakTypeTag]: Type
def typeclassFor(t: Type): Type = typeclassFor(c.WeakTypeTag(t))
def wrapObject(obj: Tree): Tree
def wrapCase0(companion: Tree, targetType: c.Type): Tree
def wrapCase1(companion: Tree, arg: String, default: Tree, typeArgs: Seq[c.Type], argTypes: Type, targetType: c.Type): Tree
Expand All @@ -23,7 +24,7 @@ trait DeriveApi[M[_]]{
def fallbackDerivation(t: Type): Option[Tree] = None
}

abstract class Derive[M[_]] extends DeriveApi[M]{
abstract class Derive extends DeriveApi{
case class TypeKey(t: c.Type) {
override def equals(o: Any) = t =:= o.asInstanceOf[TypeKey].t
}
Expand All @@ -33,24 +34,8 @@ abstract class Derive[M[_]] extends DeriveApi[M]{
case None => c.abort(c.enclosingPosition, s)
case Some(tree) => tree
}
def typeclassFor(t: Type) = {
// println("typeclassFor " + weakTypeOf[M[_]](typeclass))

weakTypeOf[M[_]](typeclass) match {
case TypeRef(a, b, _) =>
TypeRef(a, b, List(t))
case ExistentialType(_, TypeRef(a, b, _)) =>
TypeRef(a, b, List(t))
case x =>
println("Dunno Wad Dis Typeclazz Is " + x)
println(x)
println(x.getClass)
???
}
}
def freshName = c.fresh[TermName]("derive")


def derive[T: c.WeakTypeTag] = {
val tpe = weakTypeTag[T].tpe
// println(Console.YELLOW + "derive " + tpe + Console.RESET)
Expand Down
5 changes: 3 additions & 2 deletions pprint/shared/src/main/scala/pprint/PPrint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,8 @@ object Internals {
val t = weakTypeTag[T]
val d = new Deriver {
val c: c0.type = c0
def typeclass = c.weakTypeTag[pprint.PPrint[_]]
def typeclassFor[T: c0.WeakTypeTag]: c0.universe.Type =
c.weakTypeTag[pprint.PPrint[T]].tpe
}

// Fallback manually in case everything fails
Expand All @@ -413,7 +414,7 @@ object Internals {

}
}
abstract class Deriver extends Derive[pprint.PPrint]{
abstract class Deriver extends Derive{
import c._
import c.universe._

Expand Down
13 changes: 7 additions & 6 deletions upickle/shared/src/main/scala/upickle/Macros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import language.existentials
* types you don't have a Reader/Writer in scope for.
*/
object Macros {
abstract class Reading[M[_]] extends Derive[M]{
abstract class Reading extends Derive{
val c: Context
import c.universe._
def wrapObject(t: c.Tree) = q"${c.prefix}.SingletonR($t)"
Expand Down Expand Up @@ -62,7 +62,7 @@ object Macros {
def knot(t: Tree) = q"${c.prefix}.Knot.Reader(() => $t)"

}
abstract class Writing[M[_]] extends Derive[M]{
abstract class Writing extends Derive{
val c: Context
import c.universe._
def wrapObject(obj: c.Tree) = q"${c.prefix}.SingletonW($obj)"
Expand Down Expand Up @@ -119,9 +119,10 @@ object Macros {
(implicit e1: c0.WeakTypeTag[T], e2: c0.WeakTypeTag[R[_]]): c0.Expr[R[T]] = {
import c0.universe._

val res = new Reading[R]{
val res = new Reading{
val c: c0.type = c0
def typeclass = e2

def typeclassFor[T: this.c.WeakTypeTag]: this.c.universe.Type = c.weakTypeOf[R[T]]
}.derive[T]
c0.Expr[R[T]](res)
}
Expand All @@ -130,9 +131,9 @@ object Macros {
(implicit e1: c0.WeakTypeTag[T], e2: c0.WeakTypeTag[W[_]]): c0.Expr[W[T]] = {
import c0.universe._

val res = new Writing[W]{
val res = new Writing{
val c: c0.type = c0
def typeclass = e2
def typeclassFor[T: this.c.WeakTypeTag]: this.c.universe.Type = c.weakTypeOf[W[T]]
}.derive[T]
// println(res)
c0.Expr[W[T]](res)
Expand Down

0 comments on commit 3783013

Please sign in to comment.