Skip to content

Commit c8b0325

Browse files
Backport "Extra check to avoid converting block expressions on the rhs of an in…" to LTS (#21058)
Backports #20043 to the LTS branch. PR submitted by the release tooling. [skip ci]
2 parents 8b91d31 + 8869b04 commit c8b0325

File tree

4 files changed

+135
-1
lines changed

4 files changed

+135
-1
lines changed

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,8 @@ object Parsers {
794794
* 6. the opening brace does not follow a `=>`. The reason for this condition is that
795795
* rewriting back to braces does not work after `=>` (since in most cases braces are omitted
796796
* after a `=>` it would be annoying if braces were inserted).
797+
* 7. not a code block being the input to a direct symbolic function call `inst method {\n expr \n}` cannot
798+
* become `inst method :\n expr` for a fully symbolic method
797799
*/
798800
def bracesToIndented[T](body: => T, rewriteWithColon: Boolean): T = {
799801
val underColonSyntax = possibleColonOffset == in.lastOffset
@@ -807,10 +809,28 @@ object Parsers {
807809
}
808810
var canRewrite = allBraces(in.currentRegion) && // test (1)
809811
!testChars(in.lastOffset - 3, " =>") // test(6)
812+
813+
def isStartOfSymbolicFunction: Boolean =
814+
opStack.headOption.exists { x =>
815+
val bq = x.operator.isBackquoted
816+
val op = x.operator.name.toSimpleName.decode.forall {
817+
Chars.isOperatorPart
818+
}
819+
val loc = startOpening < x.offset && x.offset < endOpening
820+
val res = !bq && op && loc
821+
res
822+
}
810823
val t = enclosed(LBRACE, {
811824
canRewrite &= in.isAfterLineEnd // test (2)
812825
val curOffset = in.offset
813-
try body
826+
try {
827+
val bodyResolved = body
828+
bodyResolved match
829+
case x:(Match | Block) =>
830+
canRewrite &= !isStartOfSymbolicFunction // test (7)
831+
case _ =>
832+
bodyResolved
833+
}
814834
finally {
815835
canRewrite &= in.isAfterLineEnd && in.offset != curOffset // test (3)(4)
816836
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class CompilationTests {
6666
compileFile("tests/rewrites/i12340.scala", unindentOptions.and("-rewrite")),
6767
compileFile("tests/rewrites/i17187.scala", unindentOptions.and("-rewrite")),
6868
compileFile("tests/rewrites/i17399.scala", unindentOptions.and("-rewrite")),
69+
compileFile("tests/rewrites/i20002.scala", defaultOptions.and("-indent", "-rewrite")),
6970
).checkRewrites()
7071
}
7172

tests/rewrites/i20002.check

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
object Reactions:
2+
def main: Unit =
3+
Reactions += {
4+
case 0 =>
5+
case 1 =>
6+
}
7+
8+
Reactions run:
9+
case 0 =>
10+
case 1 =>
11+
12+
Reactions run_+ :
13+
case 0 =>
14+
case 1 =>
15+
16+
Reactions `+=`:
17+
case 0 =>
18+
case 1 =>
19+
20+
def bar: Int = ???
21+
22+
bar match
23+
case 0 =>
24+
case 1 =>
25+
26+
def partPartial(i: Int): PartialFunction[Int, Unit] =
27+
case `i` =>
28+
29+
Reactions += {
30+
val pp1 = partPartial(1)
31+
val pp2 = partPartial(2)
32+
def codeBlock =
33+
???
34+
???
35+
pp1 orElse pp2
36+
}
37+
38+
val partialFunction = partPartial(1) orElse partPartial(2)
39+
Reactions += {
40+
partialFunction
41+
}
42+
43+
def +=(f: PartialFunction[Int, Unit]) =
44+
???
45+
46+
def run (f: PartialFunction[Int, Unit]) =
47+
???
48+
49+
def run_+ (f: PartialFunction[Int, Unit]) =
50+
???
51+

tests/rewrites/i20002.scala

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
object Reactions {
2+
def main: Unit = {
3+
Reactions += {
4+
case 0 =>
5+
case 1 =>
6+
}
7+
8+
Reactions run {
9+
case 0 =>
10+
case 1 =>
11+
}
12+
13+
Reactions run_+ {
14+
case 0 =>
15+
case 1 =>
16+
}
17+
18+
Reactions `+=` {
19+
case 0 =>
20+
case 1 =>
21+
}
22+
23+
def bar: Int = ???
24+
25+
bar match {
26+
case 0 =>
27+
case 1 =>
28+
}
29+
30+
def partPartial(i: Int): PartialFunction[Int, Unit] = {
31+
case `i` =>
32+
}
33+
34+
Reactions += {
35+
val pp1 = partPartial(1)
36+
val pp2 = partPartial(2)
37+
def codeBlock = {
38+
???
39+
???
40+
}
41+
pp1 orElse pp2
42+
}
43+
44+
val partialFunction = partPartial(1) orElse partPartial(2)
45+
Reactions += {
46+
partialFunction
47+
}
48+
}
49+
50+
def +=(f: PartialFunction[Int, Unit]) = {
51+
???
52+
}
53+
54+
def run (f: PartialFunction[Int, Unit]) = {
55+
???
56+
}
57+
58+
def run_+ (f: PartialFunction[Int, Unit]) = {
59+
???
60+
}
61+
62+
}

0 commit comments

Comments
 (0)