title: "error: missing parameter type" during macro splicing
body: <p>Edit: I found my mistake - there was an error in the quasiquotes for my recursive case that was causing it to return a malformed sequence</p>
  
  <hr>
  
  <p>I am trying to create a macro that will turn a case class <code>T</code> into an <code>updateMap: Map[String, (play.api.libs.json.JsValue) =&gt; Try[(T) =&gt; T]]</code> (<a href="https://stackoverflow.com/questions/20689852/how-to-use-scala-macros-to-create-a-function-object-to-create-a-mapstring-t">How to use scala macros to create a function object (to create a Map[String, (T) =&gt; T])</a>), where the map's keys are the case class's field names - the idea being that given a <code>JsObject("key" -&gt; JsValue)</code> we can retrieve the appropriate update method from <code>updateMap</code> using the <code>key</code> and then apply the update using the <code>JsValue</code>.  I have this working in the non-recursive case, i.e. given a case class that does not have any other case classes as fields.  However, I would like to expand this macro so that it can generate an <code>updateMap</code> for case classes that contain other case classes, for example</p>
  
  <pre><code>case class Inner(innerStr: String)
  case class Outer(outerStr: String, inner: Inner)
  
  updateMap[Outer] = {
    // updateMap[Inner]
    val innerMap = Map("innerStr" -&gt; (str: String) =&gt; 
      Try { (i: Inner) =&gt; i.copy(innerStr = str) } )
  
    // updateMap[Outer]
    Map("outerStr" -&gt; (str: String) =&gt; 
      Try { (o: Outer) =&gt; o.copy(outerStr = str) },
    "inner.innerStr" -&gt; (str: String) =&gt; 
      Try { (o: Outer) =&gt; innerMap.get("innerStr").get(str).flatMap(lens =&gt; o.copy(inner = lens(o.inner))) })}
  </code></pre>
  
  <p>In other words, given <code>updateMap[Outer]</code>, I would be able to directly update the object's <code>outerStr</code> field, or else I would be able to update the object's <code>inner.innerStr</code> field, in either case getting back a <code>Try[Outer]</code>.</p>
  
  <p>The code works correctly for the non-recursive case (<code>copyMapRec[Inner]()</code>), but the recursive case (<code>copyMapRec[Outer]()</code>) is giving me a "error: missing parameter type" error - I'm assuming that I either need to provide an implicit parameter somewhere or else that I have a fundamental misunderstanding about splicing.</p>
  
  <p>The code below uses a <code>(String) =&gt; Try[(T) =&gt; T]</code> instead of a <code>(JsValue) =&gt; Try[(T) =&gt; T]</code> so that I don't need to import the play framework into my REPL.  I use implicit conversions to convert the <code>JsValue</code> (or <code>String</code>) into the appropriate type (this occurs in the <code>val x: $fieldType = str</code> line in the base case quasi quotes; if an appropriate implicit conversion isn't available then I get a compiler error).</p>
  
  <pre><code>import scala.language.experimental.macros
  
  def copyMapImplRec[T: c.WeakTypeTag](c: scala.reflect.macros.Context)(blacklist: c.Expr[String]*): c.Expr[Map[String, (String) =&gt; scala.util.Try[(T) =&gt; T]]] = {
    import c.universe._
  
    // Fields that should be omitted from the map
    val blacklistList: Seq[String] = blacklist.map(e =&gt; c.eval(c.Expr[String](c.resetAllAttrs(e.tree))))
  
    def rec(tpe: Type): c.Expr[Map[String, (String) =&gt; scala.util.Try[(T) =&gt; T]]] = {
      val typeName = tpe.typeSymbol.name.decoded
  
      // All fields in the case class's primary constructor, minus the blacklisted fields
      val fields = tpe.declarations.collectFirst {
        case m: MethodSymbol if m.isPrimaryConstructor =&gt; m
      }.get.paramss.head.filterNot(field =&gt; blacklistList.contains(typeName + "." + field.name.decoded))
  
      // Split the fields into case classes and non case classes
      val recursive = fields.filter(f =&gt; f.typeSignature.typeSymbol.isClass &amp;&amp; f.typeSignature.typeSymbol.asClass.isCaseClass)
      val nonRecursive = fields.filterNot(f =&gt; f.typeSignature.typeSymbol.isClass &amp;&amp; f.typeSignature.typeSymbol.asClass.isCaseClass)
  
      val recursiveMethods = recursive.map {
        field =&gt; {
          val fieldName = field.name
          val fieldNameDecoded = fieldName.decoded
          // Get the c.Expr[Map] for this case class
          val map = rec(field.typeSignature)
          // Construct an "inner.innerStr -&gt; " seq of tuples from the "innerStr -&gt; " seq of tuples
        q"""{
            val innerMap = $map
            innerMap.toSeq.map(tuple =&gt; ($fieldNameDecoded + "." + tuple._1) -&gt; {
            (str: String) =&gt; {
              val innerUpdate = tuple._2(str)
              innerUpdate.map(innerUpdate =&gt; (outer: $tpe) =&gt; outer.copy($fieldName = innerUpdate(outer.$fieldName)))
            }
        })}"""
        }
      }
  
      val nonRecursiveMethods = nonRecursive.map {
        field =&gt; {
          val fieldName = field.name
          val fieldNameDecoded = fieldName.decoded
          val fieldType = field.typeSignature
          val fieldTypeName = fieldType.toString
          q"""{
            $fieldNameDecoded -&gt; {
              (str: String) =&gt; scala.util.Try {
                val x: $fieldType = str
                (t: $tpe) =&gt; t.copy($fieldName = x)
              }.recoverWith {
                case e: Exception =&gt; scala.util.Failure(new IllegalArgumentException("Failed to parse " + str + " as " + $typeName + "." + $fieldNameDecoded + ": " + $fieldTypeName))
              }
           }}"""
        }
      }
  
      // Splice in all of the sequences of tuples, flatten the sequence, and construct a map
      c.Expr[Map[String, (String) =&gt; scala.util.Try[(T) =&gt; T]]] {
        q"""{ Map((List(..$recursiveMethods).flatten ++ List(..$nonRecursiveMethods)):_*) }"""
      }
    }
  
    rec(weakTypeOf[T])
  
  }
  
  def copyMapRec[T](blacklist: String*) = macro copyMapImplRec[T]
  </code></pre>