Skip to content

Commit 743ab1f

Browse files
committed
Handle polymorphic overloads with apply members
When we do overloading resolution, we first replace alternatives that could not possibly match the expected type by their `apply` members if they exist, however the existing logic failed to select `apply` members from the result of a polymorphic parameterless def. We fix this by simply replacing the PolyType by its result type without making up any type variable, the resulting behavior matches the existing behavior of Scala 2 on the added test file.
1 parent 646e433 commit 743ab1f

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1518,7 +1518,15 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
15181518

15191519
/** Replace each alternative by its apply members where necessary */
15201520
def applyMembers(alt: TermRef): List[TermRef] =
1521-
if (tryApply(alt)) alt.member(nme.apply).alternatives.map(TermRef(alt, nme.apply, _))
1521+
if (tryApply(alt)) {
1522+
val qual = alt.widen match {
1523+
case pt: PolyType =>
1524+
pt.resultType
1525+
case _ =>
1526+
alt
1527+
}
1528+
qual.member(nme.apply).alternatives.map(TermRef(alt, nme.apply, _))
1529+
}
15221530
else alt :: Nil
15231531

15241532
/** Fall back from an apply method to its original alternative */

tests/neg/poly-overloads.scala

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class A {
2+
def foo1(x: Int): Int = x
3+
def foo1[T]: String => T = ???
4+
5+
foo1("") // ok
6+
7+
def foo2(x: Int): Int = x
8+
def foo2[T]: T => String = ???
9+
10+
foo2(1): String // ok
11+
foo2("") // error, because T isn't instantiated before overloading resolution is done
12+
13+
def foo3(x: Any): Any = x
14+
def foo3[T <: Int]: T => T = x => x
15+
16+
val a = foo3(1) // ok
17+
val b: Int = a // error because the non-apply alternative was chosen, like in Scala 2
18+
19+
def foo4(x: Any): Any = x
20+
def foo4[T >: Int]: T => T = x => x
21+
22+
val c = foo4(1) // ok
23+
val d: Int = c // ok
24+
}

0 commit comments

Comments
 (0)