Skip to content

Impossible to annotate public primary constructor and keep Scala 2 compatibility #2426

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
smarter opened this issue May 14, 2017 · 4 comments

Comments

@smarter
Copy link
Member

smarter commented May 14, 2017

This doesn't compile with dotty:

class Foo @deprecated("foo", "2.11.0") (x: Int)
1 |class Foo @deprecated("foo", "2.11.0") (x: Int)
  |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |    private, protected, or this expected for annotated primary constructor

Adding this does indeed fix it, but doesn't compile with Scala 2:

class Foo @deprecated("foo", "2.11.0") this(x: Int)
  • Is this an intentional difference?
  • If yes, we should at least support the old syntax under -language:Scala2
@smarter
Copy link
Member Author

smarter commented May 14, 2017

If the this syntax is intended, then I suggest we also allow it when no annotation is present for consistency, currently this does not compile with dotty:

class Foo this(x: Int)

@odersky
Copy link
Contributor

odersky commented May 14, 2017

The tricky bit for the parser is that the syntax without this is ambiguous. Consider:

class Foo @annot(x: Int)() { ... }|

Is this a class Foo() with annotation @annot(x: Int) or a class with parameters (x: Int)() and annotation annot? Even worse is this:

class Foo @annot()()() { ... }

What is a parameter for annot and what is a parameter for Foo? We'd need a disambiguation rule for this. Not sure what scalac does?

@smarter
Copy link
Member Author

smarter commented May 14, 2017

Based on experimentation, it seems that scalac only allows one parameter list in primary constructor annotations. And while annotations with multiple parameter lists typecheck in other situations, you get an ominous warning:

scala> class Foo(x: Int)(y: String)
defined class Foo

scala> @Foo(1)("foo") class Bar(x: Int)
<console>:12: warning: Implementation limitation: multiple argument lists on annotations are
currently not supported; ignoring arguments List("foo")
       @Foo(1)("foo") class Bar(x: Int)
        ^
defined class Bar

@smarter
Copy link
Member Author

smarter commented May 14, 2017

I suggest formally specifying that annotations constructors can only have one parameter list. That seems to be the status quo in Scala 2 and no one complains about it, and it removes the ambiguity without introducing new syntax.

smarter added a commit that referenced this issue May 23, 2017
Fix #2426: Use Scala-2 syntax for annotations of class constructors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants