Implicit search inside macro expansion fails

Hi, I originally asked this question on stackoverflow, but it failed to get any traction, so re-posting it here.

Consider a trait that performs “encoding” of arbitrary objects:

trait Encoder[R] {
  def encode(r: R): Array[Byte]
}

Assuming encoding of primitive types is known and custom types can be encoded by defining up a “serializer”:

trait Serializer[T] {
  def serialize(r: T): Array[Byte]
}

we can implement a macro for case class encoding by simply looping the fields and looking up type serializers implicitly. Here’s a dummy implementation that looks up the serializer for R itself (in reality we look up serializers for case class field types):

object Encoder {
  implicit def apply[R <: Product]: Encoder[R] = macro applyImpl[R]
  def applyImpl[R: c.WeakTypeTag](c: blackbox.Context): c.Expr[Encoder[R]] = {
    import c.universe._
    c.Expr[Encoder[R]](q"""
      new ${weakTypeOf[Encoder[R]]} {
        override def encode(r: ${weakTypeOf[R]}): Array[Byte] = 
          implicitly[_root_.Serializer[${weakTypeOf[R]}]].serialize(r)
        }
    """)
  }
}

Now define a base “processor”:

abstract class BaseProcessor[R: Encoder] {
  def process(r: R): Unit = {
    println(implicitly[Encoder[R]].encode(r).length)
  }
}

And try to use it:

case class Record(i: Int)

object Serializers {
  implicit def recordSerializer: Serializer[Record] = 
    (r: Record) => Array.emptyByteArray
}

import Serializers._

class Processor extends BaseProcessor[Record]

This fails to compile with:

// [error] Loader.scala:10:22: could not find implicit value for parameter e: Serializer[Record]
// [error] class Processor extends BaseProcessor[Record]
// [error]                         ^
// [error] one error found

However the following do compile:

class Processor extends BaseProcessor[Record]()(Encoder[Record]) // Compiles!
object x { class Processor extends BaseProcessor[Record] }       // Compiles!

I can’t really understand why this happens, looks like it has something to do with the Processor definition being a top level definition, since as soon as I move it inside a class/object everything works as expected. Here’s one more example that fails to compile:

object x {
  import Serializers._ // moving the import here also makes it NOT compile
  class Processor extends BaseProcessor[Record] 
}

Why does this happen and is there any way to make it work?

it would help and speed things up if you post a public git repo with your code and share it here (or at stackoverflow) … obviously, do NOT add all your project code, narrow it down to just your issue at hand, thanks !!