Skip to content

Commit b4a802a

Browse files
committed
Only insert using for applications with parentheses syntax
1 parent 7b9c5d8 commit b4a802a

File tree

6 files changed

+73
-56
lines changed

6 files changed

+73
-56
lines changed

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

+13-15
Original file line numberDiff line numberDiff line change
@@ -130,27 +130,25 @@ trait Migrations:
130130
def implicitParams(tree: Tree, tp: MethodOrPoly, pt: FunProto)(using Context): Unit =
131131
val mversion = mv.ImplicitParamsWithoutUsing
132132
if tp.companion == ImplicitMethodType && pt.applyKind != ApplyKind.Using && pt.args.nonEmpty then
133-
val rewriteMsg = Message.rewriteNotice("This code", mversion.patchFrom)
133+
// The application can only be rewritten if it uses parentheses syntax.
134+
// See issue #22927 and related tests.
135+
val hasParentheses =
136+
ctx.source.content
137+
.slice(tree.span.end, pt.args.head.span.start)
138+
.exists(_ == '(')
139+
val rewriteMsg =
140+
if hasParentheses then
141+
Message.rewriteNotice("This code", mversion.patchFrom)
142+
else
143+
""
134144
report.errorOrMigrationWarning(
135145
em"""Implicit parameters should be provided with a `using` clause.$rewriteMsg
136146
|To disable the warning, please use the following option:
137147
| "-Wconf:msg=Implicit parameters should be provided with a `using` clause:s"
138148
|""",
139149
pt.args.head.srcPos, mversion)
140-
if mversion.needsPatch then
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), ")")
150+
if hasParentheses && mversion.needsPatch then
151+
patch(Span(pt.args.head.span.start), "using ")
154152
end implicitParams
155153

156154
end Migrations

Diff for: tests/rewrites/i22731.check

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ object Decoder:
66
inline def apply[T](implicit f: () => Unit): Decoder[T] = ???
77

88
object Input:
9-
given Decoder[Input] = Decoder(using { () =>
9+
given Decoder[Input] = Decoder { () =>
1010
Input("")
11-
})
11+
}

Diff for: tests/rewrites/i22731b.check

+29-28
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,49 @@ def foo(implicit f: () => Unit): Unit = ???
22
def bar(a: Int)(implicit f: () => Unit): Unit = ???
33

44
@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 () =>
5+
// `using` can automatically be added when the application is done with parentheses
6+
foo ( using () => 43 )
7+
foo ( using () =>
178
val x = 42
189
43
1910
)
20-
foo(using () =>
11+
foo( using () =>
2112
val x = 42
2213
43
2314
)
24-
foo(using () =>
15+
foo (using () =>
2516
val x = 42
2617
43
2718
)
28-
bar(1)(using () =>
19+
bar(1) ( using () =>
2920
val x = 42
3021
43 )
3122

32-
// Trailing lambdas with column and indentation:
33-
foo(using () =>
34-
43)
35-
foo(using () =>
23+
// `using` cannot automatically be added when the application is done with trailing lambda syntax
24+
foo { () => 43 }
25+
foo { () => val x = 42; 43 }
26+
foo{ () => val x = 42; 43 }
27+
foo {() => val x = 42; 43}
28+
bar(1) { () =>
29+
val x = 42
30+
43 }
31+
foo: () =>
32+
43
33+
foo : () =>
3634
val x = 42
37-
43)
38-
foo(using () =>
35+
43
36+
foo :() =>
3937
val x = 42
40-
43)
41-
foo(using () =>
38+
43
39+
foo
40+
: () =>
4241
val x = 42
43-
43)
44-
foo(using () =>
42+
43
43+
foo
44+
:
45+
() =>
4546
val x = 42
46-
43)
47-
bar(1)(using () =>
47+
43
48+
bar(1) : () =>
4849
val x = 42
49-
43)
50+
43

Diff for: tests/rewrites/i22731b.scala

+9-11
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,7 @@ def foo(implicit f: () => Unit): Unit = ???
22
def bar(a: Int)(implicit f: () => Unit): Unit = ???
33

44
@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:
5+
// `using` can automatically be added when the application is done with parentheses
156
foo ( () => 43 )
167
foo ( () =>
178
val x = 42
@@ -29,7 +20,14 @@ def bar(a: Int)(implicit f: () => Unit): Unit = ???
2920
val x = 42
3021
43 )
3122

32-
// Trailing lambdas with column and indentation:
23+
// `using` cannot automatically be added when the application is done with trailing lambda syntax
24+
foo { () => 43 }
25+
foo { () => val x = 42; 43 }
26+
foo{ () => val x = 42; 43 }
27+
foo {() => val x = 42; 43}
28+
bar(1) { () =>
29+
val x = 42
30+
43 }
3331
foo: () =>
3432
43
3533
foo : () =>

Diff for: tests/warn/i22731.check

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-- Warning: tests/warn/i22731.scala:5:11 -------------------------------------------------------------------------------
2+
5 | foo ( () => 43 ) // warn
3+
| ^^^^^^^^
4+
| Implicit parameters should be provided with a `using` clause.
5+
| This code can be rewritten automatically under -rewrite -source 3.7-migration.
6+
| To disable the warning, please use the following option:
7+
| "-Wconf:msg=Implicit parameters should be provided with a `using` clause:s"
8+
-- Warning: tests/warn/i22731.scala:7:6 --------------------------------------------------------------------------------
9+
7 | foo { () => 43 } // warn
10+
| ^^^^^^^^^^^^
11+
| Implicit parameters should be provided with a `using` clause.
12+
| To disable the warning, please use the following option:
13+
| "-Wconf:msg=Implicit parameters should be provided with a `using` clause:s"

Diff for: tests/warn/i22731.scala

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
def foo(implicit f: () => Unit): Unit = ???
2+
3+
@main def main =
4+
// `using` can automatically be added when the application is done with parentheses
5+
foo ( () => 43 ) // warn
6+
// `using` cannot automatically be added when the application is done with trailing lambda syntax
7+
foo { () => 43 } // warn

0 commit comments

Comments
 (0)