Search code examples
scalascala-macrosscala-3scala-compiler

Can I control the order in which macros are compiled in Scala 3?


Suppose I want to use macros in Scala 3 to count the number of places a certain method doSomething() was used in the code:

// Macros.scala

import scala.quoted.{Expr, Quotes}

object Macros {
  private var count: Int = 0

  inline def doSomething() = ${increment()}

  private def increment()(using Quotes) =
    count = count + 1
    Expr("some result")
    
  inline def callCount() = ${getCount()}
  
  private def getCount()(using Quotes) =
    Expr(count)
}

And I have an object that uses doSomething() a few times:

// Runner.scala

object Runner {
  def run() =
    Macros.doSomething()
    Macros.doSomething()
    Macros.doSomething()
}

And I want to show, at runtime, the call count:

// Main.scala

object Main {
  def main(args: Array[String]): Unit =
    println(Macros.callCount())
}

Depending on the order in which these macros were compiled, the main function will print either 0 or 3. If I could control this order, I would instruct the compiler to compile Main.scala last, so that I get the expected value 3. Is that possible?


Solution

  • No, there's no way to control it, and you just mustn't write that kind of code.