Skip to content

Commit 35f07b2

Browse files
authored
Backport "Fix regression #17245: Overloaded methods with ClassTags" (#18329)
Backports #18286
2 parents ee25abf + 5f2450a commit 35f07b2

File tree

2 files changed

+48
-24
lines changed

2 files changed

+48
-24
lines changed

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

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2062,31 +2062,35 @@ trait Applications extends Compatibility {
20622062
if isDetermined(alts2) then alts2
20632063
else resolveMapped(alts1, _.widen.appliedTo(targs1.tpes), pt1)
20642064

2065-
case defn.FunctionOf(args, resultType, _) =>
2066-
narrowByTypes(alts, args, resultType)
2067-
20682065
case pt =>
2069-
val compat = alts.filterConserve(normalizedCompatible(_, pt, keepConstraint = false))
2070-
if (compat.isEmpty)
2071-
/*
2072-
* the case should not be moved to the enclosing match
2073-
* since SAM type must be considered only if there are no candidates
2074-
* For example, the second f should be chosen for the following code:
2075-
* def f(x: String): Unit = ???
2076-
* def f: java.io.OutputStream = ???
2077-
* new java.io.ObjectOutputStream(f)
2078-
*/
2079-
pt match {
2080-
case SAMType(mtp) =>
2081-
narrowByTypes(alts, mtp.paramInfos, mtp.resultType)
2082-
case _ =>
2083-
// pick any alternatives that are not methods since these might be convertible
2084-
// to the expected type, or be used as extension method arguments.
2085-
val convertible = alts.filterNot(alt =>
2086-
normalize(alt, IgnoredProto(pt)).widenSingleton.isInstanceOf[MethodType])
2087-
if convertible.length == 1 then convertible else compat
2088-
}
2089-
else compat
2066+
val compat0 = pt match
2067+
case defn.FunctionOf(args, resType, _) =>
2068+
narrowByTypes(alts, args, resType)
2069+
case _ =>
2070+
Nil
2071+
if (compat0.isEmpty) then
2072+
val compat = alts.filterConserve(normalizedCompatible(_, pt, keepConstraint = false))
2073+
if (compat.isEmpty)
2074+
/*
2075+
* the case should not be moved to the enclosing match
2076+
* since SAM type must be considered only if there are no candidates
2077+
* For example, the second f should be chosen for the following code:
2078+
* def f(x: String): Unit = ???
2079+
* def f: java.io.OutputStream = ???
2080+
* new java.io.ObjectOutputStream(f)
2081+
*/
2082+
pt match {
2083+
case SAMType(mtp) =>
2084+
narrowByTypes(alts, mtp.paramInfos, mtp.resultType)
2085+
case _ =>
2086+
// pick any alternatives that are not methods since these might be convertible
2087+
// to the expected type, or be used as extension method arguments.
2088+
val convertible = alts.filterNot(alt =>
2089+
normalize(alt, IgnoredProto(pt)).widenSingleton.isInstanceOf[MethodType])
2090+
if convertible.length == 1 then convertible else compat
2091+
}
2092+
else compat
2093+
else compat0
20902094
}
20912095

20922096
/** The type of alternative `alt` after instantiating its first parameter

tests/pos/i17245.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import scala.reflect.ClassTag
2+
3+
trait MockSettings
4+
5+
object Mockito {
6+
def mock[T : ClassTag]: T = ???
7+
def mock[T : ClassTag](settings: MockSettings): T = ???
8+
}
9+
10+
trait Channel
11+
type OnChannel = Channel => Any
12+
13+
@main def Test =
14+
val case1: OnChannel = Mockito.mock[OnChannel]
15+
val case2: OnChannel = Mockito.mock
16+
val case3 = Mockito.mock[OnChannel]
17+
val case4: OnChannel = Mockito.mock[OnChannel](summon[ClassTag[OnChannel]])
18+
19+
// not a regressive case, but an added improvement with the fix for the above
20+
val case5: Channel => Any = Mockito.mock[Channel => Any]

0 commit comments

Comments
 (0)