Skip to content

Commit

Permalink
Backport "Fix regression #17245: Overloaded methods with ClassTags" (#…
Browse files Browse the repository at this point in the history
…18329)

Backports #18286
  • Loading branch information
Kordyjan committed Aug 9, 2023
2 parents ee25abf + 5f2450a commit 35f07b2
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 24 deletions.
52 changes: 28 additions & 24 deletions compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2062,31 +2062,35 @@ trait Applications extends Compatibility {
if isDetermined(alts2) then alts2
else resolveMapped(alts1, _.widen.appliedTo(targs1.tpes), pt1)

case defn.FunctionOf(args, resultType, _) =>
narrowByTypes(alts, args, resultType)

case pt =>
val compat = alts.filterConserve(normalizedCompatible(_, pt, keepConstraint = false))
if (compat.isEmpty)
/*
* the case should not be moved to the enclosing match
* since SAM type must be considered only if there are no candidates
* For example, the second f should be chosen for the following code:
* def f(x: String): Unit = ???
* def f: java.io.OutputStream = ???
* new java.io.ObjectOutputStream(f)
*/
pt match {
case SAMType(mtp) =>
narrowByTypes(alts, mtp.paramInfos, mtp.resultType)
case _ =>
// pick any alternatives that are not methods since these might be convertible
// to the expected type, or be used as extension method arguments.
val convertible = alts.filterNot(alt =>
normalize(alt, IgnoredProto(pt)).widenSingleton.isInstanceOf[MethodType])
if convertible.length == 1 then convertible else compat
}
else compat
val compat0 = pt match
case defn.FunctionOf(args, resType, _) =>
narrowByTypes(alts, args, resType)
case _ =>
Nil
if (compat0.isEmpty) then
val compat = alts.filterConserve(normalizedCompatible(_, pt, keepConstraint = false))
if (compat.isEmpty)
/*
* the case should not be moved to the enclosing match
* since SAM type must be considered only if there are no candidates
* For example, the second f should be chosen for the following code:
* def f(x: String): Unit = ???
* def f: java.io.OutputStream = ???
* new java.io.ObjectOutputStream(f)
*/
pt match {
case SAMType(mtp) =>
narrowByTypes(alts, mtp.paramInfos, mtp.resultType)
case _ =>
// pick any alternatives that are not methods since these might be convertible
// to the expected type, or be used as extension method arguments.
val convertible = alts.filterNot(alt =>
normalize(alt, IgnoredProto(pt)).widenSingleton.isInstanceOf[MethodType])
if convertible.length == 1 then convertible else compat
}
else compat
else compat0
}

/** The type of alternative `alt` after instantiating its first parameter
Expand Down
20 changes: 20 additions & 0 deletions tests/pos/i17245.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import scala.reflect.ClassTag

trait MockSettings

object Mockito {
def mock[T : ClassTag]: T = ???
def mock[T : ClassTag](settings: MockSettings): T = ???
}

trait Channel
type OnChannel = Channel => Any

@main def Test =
val case1: OnChannel = Mockito.mock[OnChannel]
val case2: OnChannel = Mockito.mock
val case3 = Mockito.mock[OnChannel]
val case4: OnChannel = Mockito.mock[OnChannel](summon[ClassTag[OnChannel]])

// not a regressive case, but an added improvement with the fix for the above
val case5: Channel => Any = Mockito.mock[Channel => Any]

0 comments on commit 35f07b2

Please sign in to comment.