Skip to content

Commit 1b29119

Browse files
committed
Merge pull request #1179 from liufengyun/fix-issue-1059
support `xs @ _*` and `_*` in Scala2 mode
2 parents f8ebf77 + 72b44d9 commit 1b29119

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

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

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,19 @@ object Parsers {
259259
} finally inFunReturnType = saved
260260
}
261261

262+
private val isScala2Mode =
263+
ctx.settings.language.value.contains(nme.Scala2.toString)
264+
265+
def migrationWarningOrError(msg: String, offset: Int = in.offset) =
266+
if (isScala2Mode)
267+
ctx.migrationWarning(msg, source atPos Position(offset))
268+
else
269+
syntaxError(msg, offset)
270+
262271
/** Cannot use ctx.featureEnabled because accessing the context would force too much */
263272
private def testScala2Mode(msg: String, pos: Position = Position(in.offset)) = {
264-
val s2 = ctx.settings.language.value.contains(nme.Scala2.toString)
265-
if (s2) ctx.migrationWarning(msg, source atPos pos)
266-
s2
273+
if (isScala2Mode) ctx.migrationWarning(msg, source atPos pos)
274+
isScala2Mode
267275
}
268276

269277
/* ---------- TREE CONSTRUCTION ------------------------------------------- */
@@ -1309,7 +1317,20 @@ object Parsers {
13091317
*/
13101318
val pattern2 = () => infixPattern() match {
13111319
case p @ Ident(name) if isVarPattern(p) && in.token == AT =>
1312-
atPos(p.pos.start, in.skipToken()) { Bind(name, infixPattern()) }
1320+
val pos = in.skipToken()
1321+
1322+
// compatibility for Scala2 `x @ _*` syntax
1323+
infixPattern() match {
1324+
case pt @ Ident(tpnme.WILDCARD_STAR) =>
1325+
migrationWarningOrError("The syntax `x @ _*' is no longer supported; use `x : _*' instead", p.pos.start)
1326+
atPos(p.pos.start, pos) { Typed(p, pt) }
1327+
case p =>
1328+
atPos(p.pos.start, pos) { Bind(name, p) }
1329+
}
1330+
case p @ Ident(tpnme.WILDCARD_STAR) =>
1331+
// compatibility for Scala2 `_*` syntax
1332+
migrationWarningOrError("The syntax `_*' is no longer supported; use `x : _*' instead", p.pos.start)
1333+
atPos(p.pos.start) { Typed(Ident(nme.WILDCARD), p) }
13131334
case p =>
13141335
p
13151336
}
@@ -1337,7 +1358,15 @@ object Parsers {
13371358
case t => simplePatternRest(t)
13381359
}
13391360
case USCORE =>
1340-
wildcardIdent()
1361+
val wildIndent = wildcardIdent()
1362+
1363+
// compatibility for Scala2 `x @ _*` and `_*` syntax
1364+
// `x: _*' is parsed in `ascription'
1365+
if (isIdent(nme.raw.STAR)) {
1366+
in.nextToken()
1367+
if (in.token != RPAREN) syntaxError("`_*' can be used only for last argument", wildIndent.pos)
1368+
atPos(wildIndent.pos) { Ident(tpnme.WILDCARD_STAR) }
1369+
} else wildIndent
13411370
case LPAREN =>
13421371
atPos(in.offset) { makeTupleOrParens(inParens(patternsOpt())) }
13431372
case LBRACE =>

tests/neg/i1059.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object Repeated {
2+
val list = List(1, 2, 3)
3+
4+
list match {
5+
case List(_, _, _, _ @ _*) => 0 // error: only allowed in Scala2 mode
6+
case List(_, _, _*) => 1 // error: only allowed in Scala2 mode
7+
case List(_, _: _*) => 2
8+
case Nil => 3
9+
}
10+
}

tests/pos-scala2/i1059.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object Repeated {
2+
val list = List(1, 2, 3)
3+
4+
list match {
5+
case List(_, _, _, _ @ _*) => 0
6+
case List(_, _, _*) => 1
7+
case List(_, _: _*) => 2
8+
case Nil => 3
9+
}
10+
}

0 commit comments

Comments
 (0)