Skip to content

Commit 14afbe9

Browse files
committed
Keep old rules under scala-2 compatibility mode
Issue a migration warning where the handling of braces changes
1 parent 2673222 commit 14afbe9

File tree

7 files changed

+49
-5
lines changed

7 files changed

+49
-5
lines changed

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,6 +1278,17 @@ object Parsers {
12781278
if (in.token == COLONEOL) in.nextToken()
12791279
}
12801280

1281+
def argumentStart(): Unit =
1282+
colonAtEOLOpt()
1283+
if in.isScala2CompatMode && in.isNewLine && in.next.token == LBRACE then
1284+
in.nextToken()
1285+
if in.indentWidth(in.offset) == in.currentRegion.indentWidth then
1286+
in.errorOrMigrationWarning(
1287+
i"""This opening brace will start a new statement in Scala 3.
1288+
|It needs to be indented to the right to keep being treated as
1289+
|an argument to the previous expression.${rewriteNotice()}""")
1290+
patch(source, Span(in.offset), " ")
1291+
12811292
def possibleTemplateStart(isNew: Boolean = false): Unit =
12821293
in.observeColonEOL()
12831294
if in.token == COLONEOL then
@@ -1468,7 +1479,7 @@ object Parsers {
14681479
val refinedType: () => Tree = () => refinedTypeRest(withType())
14691480

14701481
def refinedTypeRest(t: Tree): Tree = {
1471-
colonAtEOLOpt()
1482+
argumentStart()
14721483
if (in.isNestedStart)
14731484
refinedTypeRest(atSpan(startOffset(t)) { RefinedTypeTree(rejectWildcardType(t), refinement()) })
14741485
else t
@@ -2222,7 +2233,7 @@ object Parsers {
22222233
}
22232234

22242235
def simpleExprRest(t: Tree, canApply: Boolean = true): Tree = {
2225-
if canApply then colonAtEOLOpt()
2236+
if (canApply) argumentStart()
22262237
in.token match {
22272238
case DOT =>
22282239
in.nextToken()
@@ -2298,7 +2309,7 @@ object Parsers {
22982309
/** ArgumentExprss ::= {ArgumentExprs}
22992310
*/
23002311
def argumentExprss(fn: Tree): Tree = {
2301-
colonAtEOLOpt()
2312+
argumentStart()
23022313
if (in.token == LPAREN || in.isNestedStart) argumentExprss(mkApply(fn, argumentExprs()))
23032314
else fn
23042315
}
@@ -3323,7 +3334,7 @@ object Parsers {
33233334
*/
33243335
def selfInvocation(): Tree =
33253336
atSpan(accept(THIS)) {
3326-
colonAtEOLOpt()
3337+
argumentStart()
33273338
argumentExprss(mkApply(Ident(nme.CONSTRUCTOR), argumentExprs()))
33283339
}
33293340

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ object Scanners {
436436
}
437437

438438
def isContinuingParens() =
439-
openParensTokens.contains(token) && !pastBlankLine && !isScala2Mode
439+
openParensTokens.contains(token) && !pastBlankLine && !isScala2CompatMode
440440

441441
/** The indentation width of the given offset */
442442
def indentWidth(offset: Offset): IndentWidth = {

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class CompilationTests extends ParallelTesting {
129129
compileFile("tests/neg-custom-args/i3246.scala", scala2CompatMode),
130130
compileFile("tests/neg-custom-args/overrideClass.scala", scala2CompatMode),
131131
compileFile("tests/neg-custom-args/ovlazy.scala", scala2CompatMode.and("-migration", "-Xfatal-warnings")),
132+
compileFile("tests/neg-custom-args/newline-braces.scala", scala2CompatMode.and("-migration", "-Xfatal-warnings")),
132133
compileFile("tests/neg-custom-args/autoTuplingTest.scala", defaultOptions.andLanguageFeature("noAutoTupling")),
133134
compileFile("tests/neg-custom-args/nopredef.scala", defaultOptions.and("-Yno-predef")),
134135
compileFile("tests/neg-custom-args/noimports.scala", defaultOptions.and("-Yno-imports")),
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- Error: tests/neg-custom-args/newline-braces.scala:3:2 ---------------------------------------------------------------
2+
3 | { x => // error (migration)
3+
| ^
4+
| This opening brace will start a new statement in Scala 3.
5+
| It needs to be indented to the right to keep being treated as
6+
| an argument to the previous expression.
7+
| This construct can be rewritten automatically under -rewrite.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def f: List[Int] = {
2+
List(1, 2, 3).map // no newline inserted here in Scala-2 compat mode
3+
{ x => // error (migration)
4+
x + 1
5+
}
6+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
val (x, y) =
2+
try {
3+
???
4+
(1, 2)
5+
}
6+
catch {
7+
case e if !true =>
8+
val x = 2
9+
val foo = e match {
10+
case e: java.io.IOException => ???
11+
}
12+
(1, 2)
13+
}

tests/pos-scala2/newline-braces.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def f: List[Int] = {
2+
List(1, 2, 3).map // no newline inserted here in Scala-2 compat mode
3+
{ x =>
4+
x + 1
5+
}
6+
}

0 commit comments

Comments
 (0)