@@ -1544,7 +1544,7 @@ trait Applications extends Compatibility {
15441544 * Two trials: First, without implicits or SAM conversions enabled. Then,
15451545 * if the first finds no eligible candidates, with implicits and SAM conversions enabled.
15461546 */
1547- def resolveOverloaded (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] = {
1547+ def resolveOverloaded (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] =
15481548 record(" resolveOverloaded" )
15491549
15501550 /** Is `alt` a method or polytype whose result type after the first value parameter
@@ -1590,15 +1590,26 @@ trait Applications extends Compatibility {
15901590 case _ => chosen
15911591 }
15921592
1593- def resolve (alts : List [TermRef ]) = {
1594- var found = resolveOverloaded(alts, pt, Nil )(ctx.retractMode(Mode .ImplicitsEnabled ))
1595- if (found.isEmpty && ctx.mode.is(Mode .ImplicitsEnabled ))
1596- found = resolveOverloaded(alts, pt, Nil )
1597- found match {
1593+ def resolve (alts : List [TermRef ]): List [TermRef ] =
1594+ pt match
1595+ case pt : FunProto =>
1596+ if pt.isUsingApply then
1597+ val alts0 = alts.filterConserve { alt =>
1598+ val mt = alt.widen.stripPoly
1599+ mt.isImplicitMethod || mt.isContextualMethod
1600+ }
1601+ if alts0 ne alts then return resolve(alts0)
1602+ else if alts.exists(_.widen.stripPoly.isContextualMethod) then
1603+ return resolveMapped(alts, alt => stripImplicit(alt.widen), pt)
1604+ case _ =>
1605+
1606+ var found = resolveOverloaded1(alts, pt)(using ctx.retractMode(Mode .ImplicitsEnabled ))
1607+ if found.isEmpty && ctx.mode.is(Mode .ImplicitsEnabled ) then
1608+ found = resolveOverloaded1(alts, pt)
1609+ found match
15981610 case alt :: Nil => adaptByResult(alt, alts) :: Nil
15991611 case _ => found
1600- }
1601- }
1612+ end resolve
16021613
16031614 /** Try an apply method, if
16041615 * - the result is applied to value arguments and alternative is not a method, or
@@ -1634,15 +1645,16 @@ trait Applications extends Compatibility {
16341645 resolve(expanded).map(retract)
16351646 }
16361647 else resolve(alts)
1637- }
1648+ end resolveOverloaded
16381649
16391650 /** This private version of `resolveOverloaded` does the bulk of the work of
1640- * overloading resolution, but does not do result adaptation. It might be
1641- * called twice from the public `resolveOverloaded` method, once with
1651+ * overloading resolution, but does neither result adaptation nor apply insertion.
1652+ * It might be called twice from the public `resolveOverloaded` method, once with
16421653 * implicits and SAM conversions enabled, and once without.
16431654 */
1644- private def resolveOverloaded (alts : List [TermRef ], pt : Type , targs : List [Type ])(implicit ctx : Context ): List [TermRef ] =
1645- record(" resolveOverloaded/2" )
1655+ private def resolveOverloaded1 (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] =
1656+ trace(i " resolve over $alts%, %, pt = $pt" , typr, show = true ) {
1657+ record(" resolveOverloaded1" )
16461658
16471659 def isDetermined (alts : List [TermRef ]) = alts.isEmpty || alts.tail.isEmpty
16481660
@@ -1707,22 +1719,6 @@ trait Applications extends Compatibility {
17071719 case _ => arg
17081720 end normArg
17091721
1710- /** Resolve overloading by mapping to a different problem where each alternative's
1711- * type is mapped with `f`, alternatives with non-existing types are dropped, and the
1712- * expected type is `pt`. Map the results back to the original alternatives.
1713- */
1714- def resolveMapped (alts : List [TermRef ], f : TermRef => Type , pt : Type ): List [TermRef ] =
1715- val reverseMapping = alts.flatMap { alt =>
1716- val t = f(alt)
1717- if t.exists then
1718- Some ((TermRef (NoPrefix , alt.symbol.asTerm.copy(info = t)), alt))
1719- else
1720- None
1721- }
1722- val mapped = reverseMapping.map(_._1)
1723- overload.println(i " resolve mapped: $mapped" )
1724- resolveOverloaded(mapped, pt, targs).map(reverseMapping.toMap)
1725-
17261722 val candidates = pt match {
17271723 case pt @ FunProto (args, resultType) =>
17281724 val numArgs = args.length
@@ -1753,25 +1749,16 @@ trait Applications extends Compatibility {
17531749
17541750 def narrowByTrees (alts : List [TermRef ], args : List [Tree ], resultType : Type ): List [TermRef ] = {
17551751 val alts2 = alts.filter(alt =>
1756- isDirectlyApplicableMethodRef(alt, targs , args, resultType)
1752+ isDirectlyApplicableMethodRef(alt, Nil , args, resultType)
17571753 )
17581754 if (alts2.isEmpty && ! ctx.isAfterTyper)
17591755 alts.filter(alt =>
1760- isApplicableMethodRef(alt, targs , args, resultType, keepConstraint = false )
1756+ isApplicableMethodRef(alt, Nil , args, resultType, keepConstraint = false )
17611757 )
17621758 else
17631759 alts2
17641760 }
17651761
1766- if pt.isUsingApply then
1767- val alts0 = alts.filterConserve { alt =>
1768- val mt = alt.widen.stripPoly
1769- mt.isImplicitMethod || mt.isContextualMethod
1770- }
1771- if alts0 ne alts then return resolveOverloaded(alts0, pt, targs)
1772- else if alts.exists(_.widen.stripPoly.isContextualMethod) then
1773- return resolveMapped(alts, alt => stripImplicit(alt.widen), pt)
1774-
17751762 val alts1 = narrowBySize(alts)
17761763 // ctx.log(i"narrowed by size: ${alts1.map(_.symbol.showDcl)}%, %")
17771764 if isDetermined(alts1) then alts1
@@ -1783,9 +1770,10 @@ trait Applications extends Compatibility {
17831770 pretypeArgs(alts2, pt)
17841771 narrowByTrees(alts2, pt.typedArgs(normArg(alts2, _, _)), resultType)
17851772
1786- case pt @ PolyProto (targs1, pt1) if targs.isEmpty =>
1787- val alts1 = alts.filter(pt.isMatchedBy(_))
1788- resolveOverloaded(alts1, pt1, targs1.tpes)
1773+ case pt @ PolyProto (targs1, pt1) =>
1774+ val alts1 = alts.filter(pt.canInstantiate)
1775+ if isDetermined(alts1) then alts1
1776+ else resolveMapped(alts1, _.widen.appliedTo(targs1.tpes), pt1)
17891777
17901778 case defn.FunctionOf (args, resultType, _, _) =>
17911779 narrowByTypes(alts, args, resultType)
@@ -1842,21 +1830,38 @@ trait Applications extends Compatibility {
18421830 if noCurriedCount == 1 then
18431831 noCurried
18441832 else if noCurriedCount > 1 && noCurriedCount < alts.length then
1845- resolveOverloaded (noCurried, pt, targs )
1833+ resolveOverloaded1 (noCurried, pt)
18461834 else
18471835 // prefer alternatves that match without default parameters
18481836 val noDefaults = alts.filter(! _.symbol.hasDefaultParams)
18491837 val noDefaultsCount = noDefaults.length
18501838 if noDefaultsCount == 1 then
18511839 noDefaults
18521840 else if noDefaultsCount > 1 && noDefaultsCount < alts.length then
1853- resolveOverloaded (noDefaults, pt, targs )
1841+ resolveOverloaded1 (noDefaults, pt)
18541842 else if deepPt ne pt then
18551843 // try again with a deeper known expected type
1856- resolveOverloaded (alts, deepPt, targs )
1844+ resolveOverloaded1 (alts, deepPt)
18571845 else
18581846 candidates
1859- end resolveOverloaded
1847+ }
1848+ end resolveOverloaded1
1849+
1850+ /** Resolve overloading by mapping to a different problem where each alternative's
1851+ * type is mapped with `f`, alternatives with non-existing types are dropped, and the
1852+ * expected type is `pt`. Map the results back to the original alternatives.
1853+ */
1854+ def resolveMapped (alts : List [TermRef ], f : TermRef => Type , pt : Type )(using Context ): List [TermRef ] =
1855+ val reverseMapping = alts.flatMap { alt =>
1856+ val t = f(alt)
1857+ if t.exists then
1858+ Some ((TermRef (NoPrefix , alt.symbol.asTerm.copy(info = t)), alt))
1859+ else
1860+ None
1861+ }
1862+ val mapped = reverseMapping.map(_._1)
1863+ overload.println(i " resolve mapped: $mapped" )
1864+ resolveOverloaded(mapped, pt).map(reverseMapping.toMap)
18601865
18611866 /** Try to typecheck any arguments in `pt` that are function values missing a
18621867 * parameter type. If the formal parameter types corresponding to a closure argument
0 commit comments