Skip to content

Commit 6b8b794

Browse files
committed
Treat first () as annotation argument
To maintain compatibility with Scala2 we a `()` argument list as belonging to a primary constructor annotation if it is the first argument list for that annotation.
1 parent 5cbe6fa commit 6b8b794

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,9 +1318,9 @@ object Parsers {
13181318
* | `(' [ExprsInParens `,'] PostfixExpr `:' `_' `*' ')'
13191319
*
13201320
* Special treatment for arguments of primary class constructor
1321-
* annotations. Empty argument lists `(` `)` get represented
1322-
* as `List(ParamNotArg)` instead of `Nil`, indicating that the
1323-
* token sequence should be interpreted as an empty parameter clause
1321+
* annotations. All empty argument lists `(` `)` follwoing the first
1322+
* get represented as `List(ParamNotArg)` instead of `Nil`, indicating that
1323+
* the token sequence should be interpreted as an empty parameter clause
13241324
* instead. `ParamNotArg` can also be produced when parsing the first
13251325
* argument (see `classConstrAnnotExpr`).
13261326
*
@@ -1329,13 +1329,15 @@ object Parsers {
13291329
* contains the tokens that need to be replayed to parse the parameter clause.
13301330
* Otherwise, `lookaheadTokens` is empty.
13311331
*/
1332-
def parArgumentExprs(): List[Tree] = {
1332+
def parArgumentExprs(first: Boolean = false): List[Tree] = {
13331333
if (inClassConstrAnnots) {
13341334
assert(lookaheadTokens.isEmpty)
13351335
saveLookahead()
13361336
accept(LPAREN)
13371337
val args =
1338-
if (in.token == RPAREN) ParamNotArg :: Nil
1338+
if (in.token == RPAREN)
1339+
if (first) Nil // first () counts as annotation argument
1340+
else ParamNotArg :: Nil
13391341
else {
13401342
openParens.change(LPAREN, +1)
13411343
try commaSeparated(argumentExpr)
@@ -1377,8 +1379,8 @@ object Parsers {
13771379
* Otherwise parse as normal.
13781380
*/
13791381
def classConstrAnnotExpr() = {
1380-
saveLookahead()
13811382
if (in.token == IDENTIFIER) {
1383+
saveLookahead()
13821384
postfixExpr() match {
13831385
case Ident(_) if in.token == COLON => ParamNotArg
13841386
case t => expr1Rest(t, Location.InParens)
@@ -1404,9 +1406,9 @@ object Parsers {
14041406
*/
14051407
def parArgumentExprss(fn: Tree): Tree =
14061408
if (in.token == LPAREN) {
1407-
val first = parArgumentExprs()
1408-
if (inClassConstrAnnots && first == ParamNotArg :: Nil) fn
1409-
else parArgumentExprss(Apply(fn, first))
1409+
val args = parArgumentExprs(first = !fn.isInstanceOf[Trees.Apply[_]])
1410+
if (inClassConstrAnnots && args == ParamNotArg :: Nil) fn
1411+
else parArgumentExprss(Apply(fn, args))
14101412
}
14111413
else fn
14121414

tests/pos/i2426.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,18 @@ class Foo @deprecated("foo", "2.11.0") (x: Int)
22

33
class Bar @deprecated(x: Int)
44

5-
class Baz @deprecated()
5+
class Baz1 @deprecated(implicit c: C)
6+
class Baz2 @deprecated()(implicit c: C)
7+
class Baz3 @deprecated()()(implicit c: C)
8+
9+
object Test {
10+
implicit val c: C = obj
11+
new Baz1
12+
new Baz2
13+
new Baz3()
14+
}
15+
16+
class D(implicit x: C)
617

718
class C
819
object obj extends C

0 commit comments

Comments
 (0)