-
Couldn't load subscription status.
- Fork 14
Description
scala> class ann(x: Int = 1, y: Int = 2) extends annotation.StaticAnnotation
class ann
scala> @ann(y = Nil.size) class K
^
warning: Usage of named or default arguments transformed this annotation
constructor call into a block. The corresponding AnnotationInfo
will contain references to local values and default getters instead
of the actual argument trees
class K
scala> typeOf[K].typeSymbol.annotations.head
val res0: $r.intp.global.AnnotationInfo = ann(x$2, x$1)
scala> typeOf[K].typeSymbol.annotations.head.original
val res1: $r.intp.global.Tree = <empty>Before typing, the annotation is represented as new ann(y = Nil.size). To construct the AnnotationInfo, that expression is type checked like ordinary code, resulting in
{
val x$1 = Nil.size
val x$2 = ann.<init>$default$1
new ann(x$2, x$1)
}The AnnotationInfo only has ann(x$2, x$1), the block is thrown away it seems, there's now way get to the actual arguments.
Ideas
- Minimum: attach the typed Block AST to the
AnnotationInfo. But IMO this is not a good solution, it leaves processing annotations too difficult. - Never create blocks in NamesDefaults when typing an annotation. Evaluation order is not a concern, so
new ann(y = Nil.size)can be typed asnew ann(<init>$default$1, Nil.size) - Improve handling of defaults. It would be great if default values defined in the annotation declaration ended up in the
AnnotationInfo, i.e.,new ann(1, Nil.size).
For the last one, the question is how to get to the default value AST. One option is to make the compiler attach it to to a symbol, so the class ann above would become
class ann(@defaultArg(1) x: Int, @defaultArg(2) y: Int) extends StaticAnnotation
object ann {
<synthetic> def <init>$default$1 : Int = 1
<synthetic> def <init>$default$2 : Int = 2
}
When constructing the AnnotationInfo from new ann(<init>$default$1, Nil.size) we can get the AST for the default from the annotation parameter symbol.
Earlier tickets: scala/bug#7656, scala/bug#9612
I did some prototyping when discussing @apiStatus (scala/scala#8820 / scala/scala@2.13.x...lrytz:constAnnDefaults). The goal here was to allow subclasses of annotations to define certain defaults, which would be great for @nowarn: scala/bug#12367.
Fixing that at the same time would be good.