From a519333ebdce3829a593529ff0ffbac413f95362 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 27 Sep 2017 21:21:47 +0200 Subject: [PATCH 1/4] Fix #3168 Don't insert apply if tree has method type It would be simply an eta-expansion followed by an application. As #3168 shows, overloading resolution gets confused by this. --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index a4fe66b932b2..099630757590 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1799,6 +1799,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit */ def tryInsertApplyOrImplicit(tree: Tree, pt: ProtoType)(fallBack: => Tree)(implicit ctx: Context): Tree = { + def isMethod(tree: Tree) = tree.tpe match { + case ref: TermRef => ref.denot.alternatives.forall(_.info.widen.isInstanceOf[MethodicType]) + case _ => false + } + def isSyntheticApply(tree: Tree): Boolean = tree match { case tree: Select => tree.getAttachment(InsertedApply).isDefined case Apply(fn, _) => fn.getAttachment(InsertedApply).isDefined @@ -1821,7 +1826,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit pt.markAsDropped() tree case _ => - if (isApplyProto(pt) || isSyntheticApply(tree)) tryImplicit + if (isApplyProto(pt) || isMethod(tree) || isSyntheticApply(tree)) tryImplicit else tryEither(tryApply(_))((_, _) => tryImplicit) } } From 9d4e8fd02efe20b029b93379a854e0ed3143a40e Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 27 Sep 2017 21:23:30 +0200 Subject: [PATCH 2/4] Add test case - also rework previous test of #3189 to be a run test, just to make sure the problem is solved. --- tests/pos/i3168.scala | 14 ++++++++++++++ tests/pos/i3189.scala | 3 --- tests/run/i3189.scala | 9 +++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 tests/pos/i3168.scala delete mode 100644 tests/pos/i3189.scala create mode 100644 tests/run/i3189.scala diff --git a/tests/pos/i3168.scala b/tests/pos/i3168.scala new file mode 100644 index 000000000000..aa4c2e812a75 --- /dev/null +++ b/tests/pos/i3168.scala @@ -0,0 +1,14 @@ +object Test { + class C { + def foo(x: Int) = 1 + def foo(x: Double) = 2 + } + + implicit class COps(val x: C) { + def foo(x: String) = 3 + } + + def test: Unit = { + (new C).foo("Hello") + } +} diff --git a/tests/pos/i3189.scala b/tests/pos/i3189.scala deleted file mode 100644 index ca06bc54af99..000000000000 --- a/tests/pos/i3189.scala +++ /dev/null @@ -1,3 +0,0 @@ -class Test[A](action: A => A) { - def this() = this(a => a) -} \ No newline at end of file diff --git a/tests/run/i3189.scala b/tests/run/i3189.scala new file mode 100644 index 000000000000..f74fe7bfc115 --- /dev/null +++ b/tests/run/i3189.scala @@ -0,0 +1,9 @@ +class Test[A](action: A => A) { + def this() = this(a => a) + def go(x: A) = action(x) +} + +object Test extends App { + assert(new Test[Int]().go(3) == 3) +} + From a02cbe424e72736b036286c0db2a65c2dee876b4 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 27 Sep 2017 21:38:43 +0200 Subject: [PATCH 3/4] Another test This one verifies that we still need the `isSyntheticApply` condition in the test whether to elide an `apply` insertion attempt. --- tests/pos/insertapply.scala | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/pos/insertapply.scala diff --git a/tests/pos/insertapply.scala b/tests/pos/insertapply.scala new file mode 100644 index 000000000000..0a692865c1a7 --- /dev/null +++ b/tests/pos/insertapply.scala @@ -0,0 +1,6 @@ +class C { + def apply: C +} +object Test { + (new C)(22) +} From c6b65cd846eed415dc6a4b45e5a1d78259799a62 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 28 Sep 2017 16:02:50 +0200 Subject: [PATCH 4/4] Fix test --- tests/neg/insertapply.scala | 6 ++++++ tests/pos/insertapply.scala | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 tests/neg/insertapply.scala delete mode 100644 tests/pos/insertapply.scala diff --git a/tests/neg/insertapply.scala b/tests/neg/insertapply.scala new file mode 100644 index 000000000000..470e950a7863 --- /dev/null +++ b/tests/neg/insertapply.scala @@ -0,0 +1,6 @@ +class C { + def apply: C +} +object Test { + (new C)(22) // error: does not take parameters +} diff --git a/tests/pos/insertapply.scala b/tests/pos/insertapply.scala deleted file mode 100644 index 0a692865c1a7..000000000000 --- a/tests/pos/insertapply.scala +++ /dev/null @@ -1,6 +0,0 @@ -class C { - def apply: C -} -object Test { - (new C)(22) -}