-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Compiler version
3.3.6, 3.7.2, 3.8.0-RC1-bin-20250814-0cf7a18-NIGHTLY
Minimized code
import scala.annotation.StaticAnnotation
import scala.quoted.*
class MyAnnot(str: String) extends StaticAnnotation
inline def myAnnotValue[T]: String = ${ myAnnotValueImpl[T] }
def myAnnotValueImpl[T: Type](using Quotes): Expr[String] = {
import quotes.reflect.*
val targetType: TypeRepr = TypeRepr.of[T]
val targetSymbol: Symbol = targetType.typeSymbol
val myAnnotSym: Symbol = TypeRepr.of[MyAnnot].typeSymbol
def extractStringConstant(term: Term): String = term match {
case Literal(StringConstant(value)) => value
}
val maybeAnnotArg: Option[String] = targetSymbol.annotations.collectFirst {
case Apply(Select(New(tpt), _), args) if tpt.tpe.typeSymbol == myAnnotSym =>
extractStringConstant(args.head)
}
Expr(maybeAnnotArg.get)
}
@MyAnnot("Hello")
class Foo
@main def run() =
println(myAnnotValue[Foo])
Output
After compiling all the source files, running the program prints Hello
as expected.
However when the argument of the annotation gets changed, e.g. @MyAnnot("Goodbye")
(without changing other files), the macro application myAnnotValue[Foo]
doesn't get reevaluated and program still prints "Hello" instead of "Goodbye" when run.
Expectation
As implementations of macros can perform arbitrary logic and inspect arbitrary pieces of the program, it might be difficult to say when a macro invocation should be reevaluated.
However, when some class is referenced explicitly by a macro invocation, recompilation of the class should trigger recompilation of the macro.
Note
The problem doesn't seem to occur if class Foo
and myAnnotValue[Foo]
are in the same file