diff options
author | Paul Phillips <paulp@improving.org> | 2011-03-31 03:59:42 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-03-31 03:59:42 +0000 |
commit | b2ca0efb2d5e20dd7c77fedc16590164c78ba603 (patch) | |
tree | 1f69d2c02498eddcc74044c1595b649aec9111d2 | |
parent | e74515bbd35f53d772d6b4a0fe9d59e10bc82c89 (diff) | |
download | scala-b2ca0efb2d5e20dd7c77fedc16590164c78ba603.tar.gz scala-b2ca0efb2d5e20dd7c77fedc16590164c78ba603.tar.bz2 scala-b2ca0efb2d5e20dd7c77fedc16590164c78ba603.zip |
Modified some typer logic to allow annotation a...
Modified some typer logic to allow annotation arguments for constants
which don't have the form Literal(_). The current logic seems to be
avoided most of the time, but scaladoc breaks when it runs into it. This
closes #4301. I can't figure out from the ticket what the deal is with
#2764 and what is presently happening, but it seems like this patch
could only improve the situation. Review by rytz.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 25 | ||||
-rw-r--r-- | test/files/neg/annot-nonconst.check | 2 |
2 files changed, 18 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 08d5f0e12d..e797acc2c5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2523,13 +2523,22 @@ trait Typers extends Modes { /** Calling constfold right here is necessary because some trees (negated * floats and literals in particular) are not yet folded. */ - def tryConst(tr: Tree, pt: Type) = typed(constfold(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 + def tryConst(tr: Tree, pt: Type): Option[LiteralAnnotArg] = { + val const: Constant = typed(constfold(tr), EXPRmode, pt) match { + case l @ Literal(c) if !l.isErroneous => c + case tree => tree.tpe match { + case ConstantType(c) => c + case tpe => null + } + } + def fail(msg: String) = { error(tr.pos, msg) ; None } + + if (const == null) + fail("annotation argument needs to be a constant; found: " + tr) + else if (const.value == null) + fail("annotation argument cannot be null") + else + Some(LiteralAnnotArg(const)) } /** Converts an untyped tree to a ClassfileAnnotArg. If the conversion fails, @@ -2575,7 +2584,7 @@ trait Typers extends Modes { def trees2ConstArg(trees: List[Tree], pt: Type): Option[ArrayAnnotArg] = { val args = trees.map(tree2ConstArg(_, pt)) if (args.exists(_.isEmpty)) None - else Some(ArrayAnnotArg(args.map(_.get).toArray)) + else Some(ArrayAnnotArg(args.flatten.toArray)) } // begin typedAnnotation diff --git a/test/files/neg/annot-nonconst.check b/test/files/neg/annot-nonconst.check index 385f066baa..e4166e08b6 100644 --- a/test/files/neg/annot-nonconst.check +++ b/test/files/neg/annot-nonconst.check @@ -11,7 +11,7 @@ class Ann2(value: String) extends ClassfileAnnotation annot-nonconst.scala:6: error: annotation argument needs to be a constant; found: n @Length(n) def foo = "foo" ^ -annot-nonconst.scala:7: error: annotation argument needs to be a constant; found: null +annot-nonconst.scala:7: error: annotation argument cannot be null @Ann2(null) def bar = "bar" ^ two warnings found |