@@ -1783,32 +1783,35 @@ trait Applications extends Compatibility {
17831783 else compat
17841784 }
17851785
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`.
1786+ /** Resolve overloading by mapping to a different problem where each alternative's
1787+ * type is mapped with `f`, alternatives with non-existing types are dropped, and the
1788+ * expected type is `pt`. Map the results back to the original alternatives.
17901789 */
1791- def advanceCandidates (argTypes : List [Type ]): List [(TermRef , TermRef )] = {
1792- def strippedType (tp : Type ): Type = tp match {
1790+ def resolveMapped (alts : List [TermRef ], f : TermRef => Type , pt : Type ): List [TermRef ] =
1791+ val reverseMapping = alts.flatMap { alt =>
1792+ val t = f(alt)
1793+ if t.exists then
1794+ Some ((TermRef (NoPrefix , alt.symbol.asTerm.copy(info = t)), alt))
1795+ else
1796+ None
1797+ }
1798+ val mapped = reverseMapping.map(_._1)
1799+ overload.println(i " resolve mapped: $mapped" )
1800+ resolveOverloaded(mapped, pt, targs).map(reverseMapping.toMap)
1801+
1802+ /** The type of alternative `alt` after instantiating its first parameter
1803+ * clause with `argTypes`.
1804+ */
1805+ def skipParamClause (argTypes : List [Type ])(alt : TermRef ): Type =
1806+ def skip (tp : Type ): Type = tp match
17931807 case tp : PolyType =>
1794- val rt = strippedType (tp.resultType)
1795- if ( rt.exists) tp.derivedLambdaType(resType = rt) else rt
1808+ val rt = skip (tp.resultType)
1809+ if rt.exists then tp.derivedLambdaType(resType = rt) else rt
17961810 case tp : MethodType =>
17971811 tp.instantiate(argTypes)
17981812 case _ =>
17991813 NoType
1800- }
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- }
1814+ skip(alt.widen)
18121815
18131816 def resultIsMethod (tp : Type ): Boolean = tp.widen.stripPoly match
18141817 case tp : MethodType => tp.resultType.isInstanceOf [MethodType ]
@@ -1821,9 +1824,7 @@ trait Applications extends Compatibility {
18211824 deepPt match
18221825 case pt @ FunProto (_, resType : FunProto ) =>
18231826 // 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
1827+ resolveMapped(candidates, skipParamClause(pt.typedArgs().tpes), resType)
18271828 case _ =>
18281829 // prefer alternatives that need no eta expansion
18291830 val noCurried = alts.filter(! resultIsMethod(_))
0 commit comments