Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala constant expressions and computed string literals

Tags:

scala

I'm running into some trickiness with Java annotations and the stipulation that their arguments must be "constants". 6.24 of the Scala 2.8 Language Specification states that "constant expressions" are any of the following (emphasis mine):

  • A literal of a value class, such as an integer
  • A string literal
  • A class constructed with Predef.classOf (§12.5)
  • An element of an enumeration from the underlying platform
  • A literal array, of the form Array(c1, ..., cn), where all of the ci’s are themselves constant expressions
  • An identifier defined by a constant value definition (§4.1).

Now, a "string literal" seems to be defined in such a way that it's really just one " " or """ """ delimited block of characters, which is pretty clear-cut. My question, then, is why given

object MyObject {
  final val MY_CONSTANT1="foo"
  final val MY_CONSTANT2="bar" + "baz"
  final val MY_CONSTANT3="qux" + "quux" + "frobozz"
}

// ...

@MyAnnotation( ??? )
def Foo(): Unit {
...

@MyAnnotation compiles and scaladocs with MY_CONSTANT1 and MY_CONSTANT2, but not MY_CONSTANT3 (I get "annotation argument needs to be a constant"). Why does MY_CONSTANT2 work at all? Is there some unspecified at-most-two-string-literals-can-combine-to-become-a-larger-one rule at work, or am I insane?

edit I'm using Scala 2.10, which seems to have fixed some annotation-related compiler errors from earlier Scala versions.

like image 740
cbmanica Avatar asked Nov 12 '13 20:11

cbmanica


Video Answer


1 Answers

You say it "compiles and scaladocs", so I'm guessing your error is when you run scaladoc, as it was for me.

With scaladoc, you get a specialized compiler that only runs to the typer phase.

One of the things it customizes in its typer is:

override def canAdaptConstantTypeToLiteral = false

Change that to true, and your trivial example will scaladoc.

The big comment at the beginning of adapt says this is the first thing it does, or rather, the zeroth thing it doesn't do when scaladocking.

*  (0) Convert expressions with constant types to literals (unless in interactive/scaladoc mode)

Just for fun, I'll try flipping the flag to see what breaks. (Edit: the scala docs build fine. The flag grew out of presentation compiler behavior, but it's not obvious to me how it applies for scaladoc.)

like image 167
som-snytt Avatar answered Oct 23 '22 09:10

som-snytt