summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala22
-rw-r--r--test/files/pos/annotations.scala5
2 files changed, 16 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 53970fc873..879dadcbed 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2601,9 +2601,14 @@ trait Typers { self: Analyzer =>
hasError = true
annotationError
}
- def needConst(tr: Tree): None.type = {
- error(tr.pos, "annotation argument needs to be a constant; found: "+tr)
- None
+
+ def tryConst(tr: Tree, pt: Type) = typed(tr, EXPRmode, pt) match {
+ // null cannot be used as constant value for classfile annotations
+ case l @ Literal(c) if !(l.isErroneous || c.value == null) =>
+ Some(LiteralAnnotArg(c))
+ case _ =>
+ error(tr.pos, "annotation argument needs to be a constant; found: "+tr)
+ None
}
/** Converts an untyped tree to a ClassfileAnnotArg. If the conversion fails,
@@ -2628,17 +2633,12 @@ trait Typers { self: Analyzer =>
!pt.typeArgs.isEmpty)
trees2ConstArg(members, pt.typeArgs.head)
else
- needConst(tree)
+ tryConst(tree, pt)
case Typed(t, _) => tree2ConstArg(t, pt)
- case tree => typed(tree, EXPRmode, pt) match {
- // null cannot be used as constant value for classfile annotations
- case l @ Literal(c) if !(l.isErroneous || c.value == null) =>
- Some(LiteralAnnotArg(c))
- case _ =>
- needConst(tree)
- }
+ case tree =>
+ tryConst(tree, pt)
}
def trees2ConstArg(trees: List[Tree], pt: Type): Option[ArrayAnnotArg] = {
val args = trees.map(tree2ConstArg(_, pt))
diff --git a/test/files/pos/annotations.scala b/test/files/pos/annotations.scala
index d1bd6ba264..5570701011 100644
--- a/test/files/pos/annotations.scala
+++ b/test/files/pos/annotations.scala
@@ -1,4 +1,5 @@
class ann(i: Int) extends Annotation
+class cfann(x: String) extends ClassfileAnnotation
// annotations on abstract types
abstract class C1[@serializable @cloneable +T, U, V[_]]
@@ -35,6 +36,10 @@ object Test {
// annotation on annotation constructor
@(ann @ann(100))(200) def foo() = 300
+
+ // #2984
+ private final val NAMESPACE = "/info"
+ @cfann(x = NAMESPACE + "/index") def index = "success"
}
// test forward references to getters / setters