Macro methods and subtypes

Suppose we want to define an HListable trait in Scala that will add a members method returning an HList of member values to any case class that extends it. This would let us write the following, for example:

So we try the following, which looks reasonable at a glance:

Unfortunately it doesn’t actually work:

The problem is that the this in the type argument to the macro is resolved too early—we don’t get the kind of late binding we generally expect in Scala. I’m using type-level lists in this example, but the problem we’re running into here is much more general, and can turn up any time you’re writing a macro method that needs information about the type of a subtype of the class or trait it’s defined in.

One solution would be to use F-bounded polymorphism:

This works…

But ugh, that’s a lot of complexity to add for this one little bit of functionality.

Another solution (seen in this Stack Overflow question, for example) is to add a type parameter to the method:

This also works…

But it’s annoying that we have to indicate that we’re talking about a User when the compiler already knows that that’s exactly what foo is.

We can get exactly what we want, though, through the magic of implicit classes:

And now:

See this Stack Overflow answer for another example of this trick in action.