Skip to content

Commit dceeef7

Browse files
committed
Restrict outdent in parens for certain region prefixes
1 parent 0ea05aa commit dceeef7

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
@@ -735,7 +735,14 @@ object Scanners {
735735
case _ => false
736736
currentRegion match
737737
case r: Indented if isEnclosedInParens(r.outer) =>
738-
insert(OUTDENT, offset)
738+
// For some region prefixes (COLONeol, EQUALS) only OUTDENT if COMMA at EOL
739+
if canStartIndentTokens.contains(r.prefix) && !statCtdTokens.contains(r.prefix) then
740+
val lookahead = LookaheadScanner()
741+
lookahead.nextToken()
742+
if lookahead.isAfterLineEnd then
743+
insert(OUTDENT, offset)
744+
else
745+
insert(OUTDENT, offset)
739746
case _ =>
740747
peekAhead()
741748
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)