Skip to content

Commit f7faa9c

Browse files
committed
Improve rewrite of inserted apply
1 parent b0b6f4d commit f7faa9c

File tree

4 files changed

+34
-21
lines changed

4 files changed

+34
-21
lines changed

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,9 @@ object Trees {
512512

513513
/** The kind of application */
514514
enum ApplyKind:
515-
case Regular // r.f(x)
516-
case Using // r.f(using x)
517-
case InfixTuple // r f (x1, ..., xN) where N != 1; needs to be treated specially for an error message in typedApply
515+
case Regular // r.f(x)
516+
case Using // r.f(using x)
517+
case InfixTuple // r f (x1, ..., xN) where N != 1; needs to be treated specially for an error message in typedApply
518518

519519
/** fun(args) */
520520
case class Apply[+T <: Untyped] private[ast] (fun: Tree[T], args: List[Tree[T]])(implicit @constructorOnly src: SourceFile)

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,21 @@ trait Applications extends Compatibility {
11101110
then originalProto.tupledDual
11111111
else originalProto
11121112

1113+
/* TODO (*) Get rid of this case. It is still syntax-based, therefore unreliable.
1114+
* It is necessary for things like `someDynamic[T](...)`, because in that case,
1115+
* somehow typedFunPart returns a tree that was typed as `TryDynamicCallType`,
1116+
* so clearly with the view that an apply insertion was necessary, but doesn't
1117+
* actually insert the apply!
1118+
* This is probably something wrong in apply insertion, but I (@sjrd) am out of
1119+
* my depth there.
1120+
* In the meantime, this makes tests pass.
1121+
*/
1122+
def isInsertedApply = fun1 match
1123+
case Select(_, nme.apply) => fun1.span.isSynthetic
1124+
case TypeApply(sel @ Select(_, nme.apply), _) => sel.span.isSynthetic
1125+
case TypeApply(fun, _) => !fun.isInstanceOf[Select] // (*) see explanatory comment
1126+
case _ => false
1127+
11131128
/** Type application where arguments come from prototype, and no implicits are inserted */
11141129
def simpleApply(fun1: Tree, proto: FunProto)(using Context): Tree =
11151130
methPart(fun1).tpe match {
@@ -1186,6 +1201,11 @@ trait Applications extends Compatibility {
11861201
case _ => ()
11871202

11881203
def maybePatchBadParensForImplicit(failedState: TyperState)(using Context): Boolean =
1204+
def rewrite(): Unit =
1205+
val replace =
1206+
if isInsertedApply then ".apply" // x() -> x.apply
1207+
else "" // f() -> f where fun1.span.end == tree.span.point
1208+
rewrites.Rewrites.patch(tree.span.withStart(fun1.span.end), replace)
11891209
var retry = false
11901210
failedState.reporter.mapBufferedMessages: dia =>
11911211
dia match
@@ -1195,7 +1215,7 @@ trait Applications extends Compatibility {
11951215
val mv = MigrationVersion.ImplicitParamsWithoutUsing
11961216
if mv.needsPatch then
11971217
retry = true
1198-
rewrites.Rewrites.patch(tree.span.withStart(tree.span.point), "") // f() -> f
1218+
rewrite()
11991219
Diagnostic.Warning(err.msg, err.pos)
12001220
else err
12011221
case _ => err
@@ -1205,21 +1225,6 @@ trait Applications extends Compatibility {
12051225
val result = fun1.tpe match {
12061226
case err: ErrorType => cpy.Apply(tree)(fun1, proto.typedArgs()).withType(err)
12071227
case TryDynamicCallType =>
1208-
val isInsertedApply = fun1 match {
1209-
case Select(_, nme.apply) => fun1.span.isSynthetic
1210-
case TypeApply(sel @ Select(_, nme.apply), _) => sel.span.isSynthetic
1211-
/* TODO Get rid of this case. It is still syntax-based, therefore unreliable.
1212-
* It is necessary for things like `someDynamic[T](...)`, because in that case,
1213-
* somehow typedFunPart returns a tree that was typed as `TryDynamicCallType`,
1214-
* so clearly with the view that an apply insertion was necessary, but doesn't
1215-
* actually insert the apply!
1216-
* This is probably something wrong in apply insertion, but I (@sjrd) am out of
1217-
* my depth there.
1218-
* In the meantime, this makes tests pass.
1219-
*/
1220-
case TypeApply(fun, _) => !fun.isInstanceOf[Select]
1221-
case _ => false
1222-
}
12231228
val tree1 = fun1 match
12241229
case Select(_, nme.apply) => tree
12251230
case _ => untpd.Apply(fun1, tree.args)

tests/rewrites/i22792.check

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@ class Foo:
88
given Permit = ???
99
@main def Test = new Foo().run
1010

11-
def otherSyntax = Foo()
11+
def ctorProxy = Foo().run
12+
13+
def otherSyntax = new Foo().apply // Foo().apply does not work
14+
15+
def kwazySyntax = new Foo() . run // that was fun

tests/rewrites/i22792.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@ class Foo:
88
given Permit = ???
99
@main def Test = new Foo().run()
1010

11-
def otherSyntax = Foo()()
11+
def ctorProxy = Foo().run()
12+
13+
def otherSyntax = new Foo()() // Foo().apply does not work
14+
15+
def kwazySyntax = new Foo() . run ( /* your args here! */ ) // that was fun

0 commit comments

Comments
 (0)