-
Notifications
You must be signed in to change notification settings - 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.