scala 2.10.2 calling a 'macro method' with generic type not work

Viewed 1665

I define following macro to transform case fields to map

   import scala.language.experimental.macros
    import scala.reflect.macros.Context

    def asMap_impl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]) = {
      import c.universe._

      val mapApply = Select(reify(Map).tree, newTermName("apply"))

      val pairs = weakTypeOf[T].declarations.collect {
        case m: MethodSymbol if m.isCaseAccessor =>
          val name = c.literal(m.name.decoded)
          val value = c.Expr(Select(t.tree, m.name))
          reify(name.splice -> value.splice).tree
      }

      c.Expr[Map[String, Any]](Apply(mapApply, pairs.toList))
    }

And the method implementation

def asMap[T](t: T) = macro asMap_impl[T]

Then I define a case class to test it

case class User(name : String)

It works fine(with scala repl):

 scala> asMap(User("foo")) res0:
 scala.collection.immutable.Map[String,String] = Map(name -> foo)

But When I wrap this method with another generic method

def printlnMap[T](t: T) = println(asMap(t))

This method always print empty map:

scala> printlnMap(User("foo"))
Map()

The type information seems lost, how to get the printlnMap to print all fields ?

1 Answers
Related