@@ -833,7 +833,7 @@ trait Applications extends Compatibility {
833833 def typedApply (tree : untpd.Apply , pt : Type )(implicit ctx : Context ): Tree = {
834834
835835 def realApply (implicit ctx : Context ): Tree = {
836- val originalProto = new FunProto (tree.args, IgnoredProto (pt))(this , tree.isGivenApply )(argCtx(tree))
836+ val originalProto = new FunProto (tree.args, IgnoredProto (pt))(this , tree.isUsingApply )(argCtx(tree))
837837 record(" typedApply" )
838838 val fun1 = typedFunPart(tree.fun, originalProto)
839839
@@ -1299,6 +1299,16 @@ trait Applications extends Compatibility {
12991299 }
13001300 }
13011301
1302+ /** Drop any implicit parameter section */
1303+ def stripImplicit (tp : Type )(using Context ): Type = tp match {
1304+ case mt : MethodType if mt.isImplicitMethod =>
1305+ stripImplicit(resultTypeApprox(mt))
1306+ case pt : PolyType =>
1307+ pt.derivedLambdaType(pt.paramNames, pt.paramInfos, stripImplicit(pt.resultType))
1308+ case _ =>
1309+ tp
1310+ }
1311+
13021312 /** Compare owner inheritance level.
13031313 * @param sym1 The first owner
13041314 * @param sym2 The second owner
@@ -1466,16 +1476,6 @@ trait Applications extends Compatibility {
14661476 else tp
14671477 }
14681478
1469- /** Drop any implicit parameter section */
1470- def stripImplicit (tp : Type ): Type = tp match {
1471- case mt : MethodType if mt.isImplicitMethod =>
1472- stripImplicit(resultTypeApprox(mt))
1473- case pt : PolyType =>
1474- pt.derivedLambdaType(pt.paramNames, pt.paramInfos, stripImplicit(pt.resultType))
1475- case _ =>
1476- tp
1477- }
1478-
14791479 def compareWithTypes (tp1 : Type , tp2 : Type ) = {
14801480 val ownerScore = compareOwner(alt1.symbol.maybeOwner, alt2.symbol.maybeOwner)
14811481 def winsType1 = isAsSpecific(alt1, tp1, alt2, tp2)
@@ -1707,6 +1707,22 @@ trait Applications extends Compatibility {
17071707 case _ => arg
17081708 end normArg
17091709
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+
17101726 val candidates = pt match {
17111727 case pt @ FunProto (args, resultType) =>
17121728 val numArgs = args.length
@@ -1747,6 +1763,15 @@ trait Applications extends Compatibility {
17471763 alts2
17481764 }
17491765
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+
17501775 val alts1 = narrowBySize(alts)
17511776 // ctx.log(i"narrowed by size: ${alts1.map(_.symbol.showDcl)}%, %")
17521777 if isDetermined(alts1) then alts1
@@ -1783,32 +1808,20 @@ trait Applications extends Compatibility {
17831808 else compat
17841809 }
17851810
1786- /** For each candidate `C`, a proxy termref paired with `C`.
1787- * The proxy termref has as symbol a copy of the original candidate symbol,
1788- * with an info that strips the first value parameter list away.
1789- * @param argTypes The types of the arguments of the FunProto `pt`.
1811+ /** The type of alternative `alt` after instantiating its first parameter
1812+ * clause with `argTypes`.
17901813 */
1791- def advanceCandidates (argTypes : List [Type ]): List [( TermRef , TermRef )] = {
1792- def strippedType (tp : Type ): Type = tp match {
1814+ def skipParamClause (argTypes : List [Type ])( alt : TermRef ) : Type =
1815+ def skip (tp : Type ): Type = tp match {
17931816 case tp : PolyType =>
1794- val rt = strippedType (tp.resultType)
1817+ val rt = skip (tp.resultType)
17951818 if (rt.exists) tp.derivedLambdaType(resType = rt) else rt
17961819 case tp : MethodType =>
17971820 tp.instantiate(argTypes)
17981821 case _ =>
17991822 NoType
18001823 }
1801- def cloneCandidate (cand : TermRef ): List [(TermRef , TermRef )] = {
1802- val strippedInfo = strippedType(cand.widen)
1803- if (strippedInfo.exists) {
1804- val sym = cand.symbol.asTerm.copy(info = strippedInfo)
1805- (TermRef (NoPrefix , sym), cand) :: Nil
1806- }
1807- else Nil
1808- }
1809- overload.println(i " look at more params: ${candidates.head.symbol}: ${candidates.map(_.widen)}%, % with $pt, [ $targs%, %] " )
1810- candidates.flatMap(cloneCandidate)
1811- }
1824+ skip(alt.widen)
18121825
18131826 def resultIsMethod (tp : Type ): Boolean = tp.widen.stripPoly match
18141827 case tp : MethodType => tp.resultType.isInstanceOf [MethodType ]
@@ -1821,9 +1834,7 @@ trait Applications extends Compatibility {
18211834 deepPt match
18221835 case pt @ FunProto (_, resType : FunProto ) =>
18231836 // try to narrow further with snd argument list
1824- val advanced = advanceCandidates(pt.typedArgs().tpes)
1825- resolveOverloaded(advanced.map(_._1), resType, Nil ) // resolve with candidates where first params are stripped
1826- .map(advanced.toMap) // map surviving result(s) back to original candidates
1837+ resolveMapped(candidates, skipParamClause(pt.typedArgs().tpes), resType)
18271838 case _ =>
18281839 // prefer alternatives that need no eta expansion
18291840 val noCurried = alts.filter(! resultIsMethod(_))
0 commit comments