scalamacrosscala-macrosscala-3

How to avoid calls to `scala.quoted.Quotes.reflectModule.reportModule.info` to be ignored in compiler output?


For debugging a scala 3.6.4 recursive macro I added many calls to quotes.reflect.report.info. But only a few are shown in the compiler output despite all the messages are different. Apparently, the compiler deduplicates messages even if they are unique.

I tried setting many different compiler options with no avail. Perhaps I am missing someone. Using System.out.println works but that skips all output configurations. I hope that the compiler reporting mechanism offers a solution.


Solution

  • In all versions of Scala (2, 3) the first message sent to: info, warn, error is being displayed under the Position that you passed there (usually the Position of macro splicing). All the others are no-ops because there is no obvious way how multiple messages could be displayed.

    This is intentional an there is no config to change it. If you want to aggregate messages, you have to aggregate them yourself with e.g. global StringBuilder

    val info = new StringBuilder
    val warn = new StringBuilder
    val error = new StringBuilder
    

    or passing around some logging context

    case class LoggingContext(...)
    def method(using LoggingContext)
    // or
    type Result[A] = List[String] => A
    def method: Result[Expr[Out]]
    

    Considering that error handling could be useful as well, it quickly becomes

    type Result[A] = List[String] => Either[Errors, A]
    

    and at this point I usually define some custom type (example from Chimney or from my future macro stdlib).