Skip to content

Commit f18ed1a

Browse files
committed
Restrict outdent in parens for certain region prefixes
1 parent a340ae9 commit f18ed1a

File tree

3 files changed

+97
-1
lines changed

3 files changed

+97
-1
lines changed

Diff for: compiler/src/dotty/tools/dotc/parsing/Scanners.scala

+8-1
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,14 @@ object Scanners {
747747
case _ => false
748748
currentRegion match
749749
case r: Indented if isEnclosedInParens(r.outer) =>
750-
insert(OUTDENT, offset)
750+
// For some region prefixes (COLONeol, EQUALS) only OUTDENT if COMMA at EOL
751+
if canStartIndentTokens.contains(r.prefix) && !statCtdTokens.contains(r.prefix) then
752+
val lookahead = LookaheadScanner()
753+
lookahead.nextToken()
754+
if lookahead.isAfterLineEnd then
755+
insert(OUTDENT, offset)
756+
else
757+
insert(OUTDENT, offset)
751758
case _ =>
752759
peekAhead()
753760
if isAfterLineEnd

Diff for: tests/neg/i22527.scala

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
//rule of thumb is COLONeol was at EOL, so COMMA must be at EOL
3+
def test: Unit =
4+
assert(
5+
identity:
6+
true, "ok" // error end of statement expected but ',' found
7+
)
8+
9+
def toss: Unit =
10+
assert(
11+
throw
12+
null, "ok" // error same
13+
)
14+
15+
def callme[A](x: => A, msg: String) = try x.toString catch case t: RuntimeException => msg
16+
17+
// not all indented regions require COMMA at EOL for OUTDENT
18+
def orElse(x: Int): Unit =
19+
callme(
20+
if x > 0 then
21+
class X extends AnyRef, Serializable // error Not found: Serializable - did you mean Specializable?
22+
true // error ',' or ')' expected, but 'true' found
23+
else
24+
false, "fail")

Diff for: tests/pos/i22527.scala

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
def f: Unit =
3+
identity(
4+
identity:
5+
class X extends AnyRef, Serializable
6+
42
7+
)
8+
9+
def g: Unit =
10+
identity(
11+
x =
12+
class X extends AnyRef, Serializable
13+
27
14+
)
15+
16+
def test: Unit =
17+
assert(
18+
identity:
19+
true,
20+
"ok"
21+
)
22+
23+
def toss: Unit =
24+
assert(
25+
throw
26+
null,
27+
"ok"
28+
)
29+
30+
def callme[A](x: => A, msg: String) = try x.toString catch case t: RuntimeException => msg
31+
32+
def orElse(x: Int): Unit =
33+
callme(
34+
if x > 0 then
35+
true
36+
else
37+
false, "fail")
38+
39+
def onlyIf(x: Int): Unit =
40+
callme(
41+
if (x > 0)
42+
true, "fail") // warn value discard
43+
44+
def h(xs: List[Int]) =
45+
xs.foldLeft(0)
46+
(
47+
(acc, x) =>
48+
acc
49+
+ x,
50+
)
51+
52+
def sum(x: Int, y: Int, z: Int) = x+y+z
53+
54+
def k(xs: List[Int], y: Int, z: Int) =
55+
xs.foldLeft(0)
56+
(
57+
(acc, x) =>
58+
sum(
59+
x
60+
+ y
61+
+ z,
62+
y,
63+
z,
64+
)
65+
)

0 commit comments

Comments
 (0)