Internal error accessing enclosing macro object via a symbol of a superclass member

29 Views Asked by At

Sorry, this title is probably not very clear ... but that seems rather appropriate when talking about scala macros :)

So, I have a class (the ApplicationInfo thingy doesn't really matter - can be anything AFAICT):

case class ApplicationInfo()
abstract class Base {
   def appInfo = new ApplicationInfo()
}
object Sub extends ApplicationInfo { 
   def foo = showInfo
}

... where `showInfo is a macro defined something like this:

def showInfoImpl(c: blackbox.Context) = {
   import c.universe
    val ai = Iterator.iterate(c.internal.enclosingOwner) { _.owner }
      .find { _.isClass }
      .getOrElse(c.abort(c.enclosingPosition, "Cannot find enclosing class"))
      .info
      .member(TermName("appInfo"))
    q"$ai"
}

(obviously, not a very useful macro - could just write appInfo instead - but this is just to demonstrate the problem)

Compiling Sub results in an error: Internal error: unable to find the outer accessor symbol of object Sub.

Interestingly, if I replace the return value with q"appInfo", that works. Also, if I add def ai = super.appInfo to Sub and then replace "appInfo" with "ai" in the macro, that works too.

So, it looks like something is broken in accessing a member of a superclass this way (which isn't very surprising, given the name c.internal ...). The question is if someone knows some sort of incantation I can use to get around this (perhaps, one of the numerous way to get to a type/class from Symbol (typeSignature vs info?, asType? toType?) or some of the magical operations on the type (dealias? etaExpand?) can help here (I know I could just try and see, but it seems kind hopeless to check every possible combination ... and besides, I am sure I am simply not aware of some of the possibilities, so I thought, I'd ask in hope that someone happens to just know).

0

There are 0 best solutions below