Skip to content

Commit c184805

Browse files
committed
Improve rewrite of inserted apply
1 parent 21e3482 commit c184805

File tree

4 files changed

+34
-21
lines changed

4 files changed

+34
-21
lines changed

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -509,9 +509,9 @@ object Trees {
509509

510510
/** The kind of application */
511511
enum ApplyKind:
512-
case Regular // r.f(x)
513-
case Using // r.f(using x)
514-
case InfixTuple // r f (x1, ..., xN) where N != 1; needs to be treated specially for an error message in typedApply
512+
case Regular // r.f(x)
513+
case Using // r.f(using x)
514+
case InfixTuple // r f (x1, ..., xN) where N != 1; needs to be treated specially for an error message in typedApply
515515

516516
/** fun(args) */
517517
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

+21-16
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,21 @@ trait Applications extends Compatibility {
11021102
then originalProto.tupledDual
11031103
else originalProto
11041104

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

11801195
def maybePatchBadParensForImplicit(failedState: TyperState)(using Context): Boolean =
1196+
def rewrite(): Unit =
1197+
val replace =
1198+
if isInsertedApply then ".apply" // x() -> x.apply
1199+
else "" // f() -> f where fun1.span.end == tree.span.point
1200+
rewrites.Rewrites.patch(tree.span.withStart(fun1.span.end), replace)
11811201
var retry = false
11821202
failedState.reporter.mapBufferedMessages: dia =>
11831203
dia match
@@ -1187,7 +1207,7 @@ trait Applications extends Compatibility {
11871207
val mv = MigrationVersion.ImplicitParamsWithoutUsing
11881208
if mv.needsPatch then
11891209
retry = true
1190-
rewrites.Rewrites.patch(tree.span.withStart(tree.span.point), "") // f() -> f
1210+
rewrite()
11911211
Diagnostic.Warning(err.msg, err.pos)
11921212
else err
11931213
case _ => err
@@ -1197,21 +1217,6 @@ trait Applications extends Compatibility {
11971217
val result = fun1.tpe match {
11981218
case err: ErrorType => cpy.Apply(tree)(fun1, proto.typedArgs()).withType(err)
11991219
case TryDynamicCallType =>
1200-
val isInsertedApply = fun1 match {
1201-
case Select(_, nme.apply) => fun1.span.isSynthetic
1202-
case TypeApply(sel @ Select(_, nme.apply), _) => sel.span.isSynthetic
1203-
/* TODO Get rid of this case. It is still syntax-based, therefore unreliable.
1204-
* It is necessary for things like `someDynamic[T](...)`, because in that case,
1205-
* somehow typedFunPart returns a tree that was typed as `TryDynamicCallType`,
1206-
* so clearly with the view that an apply insertion was necessary, but doesn't
1207-
* actually insert the apply!
1208-
* This is probably something wrong in apply insertion, but I (@sjrd) am out of
1209-
* my depth there.
1210-
* In the meantime, this makes tests pass.
1211-
*/
1212-
case TypeApply(fun, _) => !fun.isInstanceOf[Select]
1213-
case _ => false
1214-
}
12151220
val tree1 = fun1 match
12161221
case Select(_, nme.apply) => tree
12171222
case _ => untpd.Apply(fun1, tree.args)

tests/rewrites/i22792.check

+5-1
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

+5-1
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)