Skip to content

Commit b5ef0ee

Browse files
committed
Refactor resolveOverload
Introduce an abstraction to reduce to a mapped problem
1 parent fc29643 commit b5ef0ee

File tree

1 file changed

+24
-23
lines changed

1 file changed

+24
-23
lines changed

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

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)