Implicit macros not attempted when type paremeters are covariant or contravariant - is there a way around this?


#1
trait Base[-T] { ... }

object Base {
  implicit object SomeImpl1 extends Base[Int] { ... }
  implicit object SomeImpl2 extends Base[String] { ... }
  implicit def synthesize[T]: Base[T] = macro ...
}

When I remove “-” from T, the macro expansion is attempted in implicit search. When Base is covariant or contravariant in T, the the macro is never executed, only the two implicit objects are taken into account. I confirmed by placing a println inside of a macro.

Is there a way to trick Scala compiler into expanding my macro when the right implicit is not found in the current context and at the same time to benefit from covariance/contravariance?

// edit:
Actually I was a bit wrong - whitebox macros are attempted, with T = Any. That’s not very useful though, so the question stays open.


#2

One trick I found is to use a helper non contravariant trait:


trait Base[-T] { ... }

object Base {
  implicit object SomeImpl1 extends Base[Int] { ... }
  implicit object SomeImpl2 extends Base[String] { ... }
  implicit def synthetic[T](implicit s: Synthetic[T]): Base[T] = s
}

trait Synthetic[T] extends Base[T]
object Synthetic[T] {
  implicit def synthesize[T]: Synthetic[T] = macro ...  // can be blackbox
}