Skip to content

Commit 938ab46

Browse files
mbovelajafri2001
andcommitted
Fix insertion of using in applications with trailing lambda syntax
Co-Authored-By: Abdullah Arif Jafri <[email protected]>
1 parent ee9ba92 commit 938ab46

File tree

6 files changed

+142
-2
lines changed

6 files changed

+142
-2
lines changed

Diff for: compiler/src/dotty/tools/dotc/typer/Migrations.scala

+13-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,19 @@ trait Migrations:
138138
|""",
139139
pt.args.head.srcPos, mversion)
140140
if mversion.needsPatch then
141-
patch(Span(pt.args.head.span.start), "using ")
141+
// In order to insert a `using`, the application needs to be done with
142+
// parentheses syntax. See issue #22927 and related tests.
143+
patch(Span(tree.span.end, pt.args.head.span.start), "(using ")
144+
// Tentative heuristic: the application was done with parentheses syntax
145+
// if there is a `(` between the function and the first argument.
146+
val hasParentheses =
147+
ctx.source.content
148+
.slice(tree.span.end, pt.args.head.span.start)
149+
.exists(_ == '(')
150+
if !hasParentheses then
151+
// If the application wasn't done with the parentheses syntax, we need
152+
// to add a trailing closing parenthesis.
153+
patch(Span(pt.args.head.span.end), ")")
142154
end implicitParams
143155

144156
end Migrations

Diff for: compiler/test/dotty/tools/dotc/CompilationTests.scala

+4-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ class CompilationTests {
8888
compileFile("tests/rewrites/ambiguous-named-tuple-assignment.scala", defaultOptions.and("-rewrite", "-source:3.6-migration")),
8989
compileFile("tests/rewrites/i21382.scala", defaultOptions.and("-indent", "-rewrite")),
9090
compileFile("tests/rewrites/unused.scala", defaultOptions.and("-rewrite", "-Wunused:all")),
91-
compileFile("tests/rewrites/i22440.scala", defaultOptions.and("-rewrite"))
91+
compileFile("tests/rewrites/i22440.scala", defaultOptions.and("-rewrite")),
92+
compileFile("tests/rewrites/i22440.scala", defaultOptions.and("-rewrite")),
93+
compileFile("tests/rewrites/i22731.scala", defaultOptions.and("-rewrite", "-source:3.7-migration")),
94+
compileFile("tests/rewrites/i22731b.scala", defaultOptions.and("-rewrite", "-source:3.7-migration")),
9295
).checkRewrites()
9396
}
9497

Diff for: tests/rewrites/i22731.check

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Input(x: String)
2+
3+
trait Decoder[T]
4+
5+
object Decoder:
6+
inline def apply[T](implicit f: () => Unit): Decoder[T] = ???
7+
8+
object Input:
9+
given Decoder[Input] = Decoder(using { () =>
10+
Input("")
11+
})

Diff for: tests/rewrites/i22731.scala

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Input(x: String)
2+
3+
trait Decoder[T]
4+
5+
object Decoder {
6+
inline def apply[T](implicit f: () => Unit): Decoder[T] = ???
7+
}
8+
9+
object Input {
10+
given Decoder[Input] = Decoder { () =>
11+
Input("")
12+
}
13+
}

Diff for: tests/rewrites/i22731b.check

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
def foo(implicit f: () => Unit): Unit = ???
2+
def bar(a: Int)(implicit f: () => Unit): Unit = ???
3+
4+
@main def main =
5+
// Trailing lambdas with braces:
6+
foo(using { () => 43 })
7+
foo(using { () => val x = 42; 43 })
8+
foo(using { () => val x = 42; 43 })
9+
foo(using {() => val x = 42; 43})
10+
bar(1)(using { () =>
11+
val x = 42
12+
43 })
13+
14+
// Parentheses:
15+
foo(using () => 43 )
16+
foo(using () =>
17+
val x = 42
18+
43
19+
)
20+
foo(using () =>
21+
val x = 42
22+
43
23+
)
24+
foo(using () =>
25+
val x = 42
26+
43
27+
)
28+
bar(1)(using () =>
29+
val x = 42
30+
43 )
31+
32+
// Trailing lambdas with column and indentation:
33+
foo(using () =>
34+
43)
35+
foo(using () =>
36+
val x = 42
37+
43)
38+
foo(using () =>
39+
val x = 42
40+
43)
41+
foo(using () =>
42+
val x = 42
43+
43)
44+
foo(using () =>
45+
val x = 42
46+
43)
47+
bar(1)(using () =>
48+
val x = 42
49+
43)

Diff for: tests/rewrites/i22731b.scala

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
def foo(implicit f: () => Unit): Unit = ???
2+
def bar(a: Int)(implicit f: () => Unit): Unit = ???
3+
4+
@main def main =
5+
// Trailing lambdas with braces:
6+
foo { () => 43 }
7+
foo { () => val x = 42; 43 }
8+
foo{ () => val x = 42; 43 }
9+
foo {() => val x = 42; 43}
10+
bar(1) { () =>
11+
val x = 42
12+
43 }
13+
14+
// Parentheses:
15+
foo ( () => 43 )
16+
foo ( () =>
17+
val x = 42
18+
43
19+
)
20+
foo( () =>
21+
val x = 42
22+
43
23+
)
24+
foo (() =>
25+
val x = 42
26+
43
27+
)
28+
bar(1) ( () =>
29+
val x = 42
30+
43 )
31+
32+
// Trailing lambdas with column and indentation:
33+
foo: () =>
34+
43
35+
foo : () =>
36+
val x = 42
37+
43
38+
foo :() =>
39+
val x = 42
40+
43
41+
foo
42+
: () =>
43+
val x = 42
44+
43
45+
foo
46+
:
47+
() =>
48+
val x = 42
49+
43
50+
bar(1) : () =>
51+
val x = 42
52+
43

0 commit comments

Comments
 (0)