@@ -11,6 +11,7 @@ import Trees.Untyped
1111import Contexts ._
1212import Flags ._
1313import Symbols ._
14+ import Denotations .Denotation
1415import Types ._
1516import Decorators ._
1617import ErrorReporting ._
@@ -1204,8 +1205,12 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
12041205 * result matching `resultType`?
12051206 */
12061207 def hasExtensionMethod (tp : Type , name : TermName , argType : Type , resultType : Type )(implicit ctx : Context ) = {
1207- val mbr = tp.memberBasedOnFlags(name, required = ExtensionMethod )
1208- mbr.exists && isApplicable(tp.select(name, mbr), argType :: Nil , resultType)
1208+ def qualifies (mbr : Denotation ) =
1209+ mbr.exists && isApplicable(tp.select(name, mbr), argType :: Nil , resultType)
1210+ tp.memberBasedOnFlags(name, required = ExtensionMethod ) match {
1211+ case mbr : SingleDenotation => qualifies(mbr)
1212+ case mbr => mbr.hasAltWith(qualifies(_))
1213+ }
12091214 }
12101215
12111216 /** Compare owner inheritance level.
@@ -1627,16 +1632,50 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
16271632 }
16281633 else compat
16291634 }
1635+
1636+ /** For each candidate `C`, a proxy termref paired with `C`.
1637+ * The proxy termref has as symbol a copy of the original candidate symbol,
1638+ * with an info that strips the first value parameter list away.
1639+ * @param argTypes The types of the arguments of the FunProto `pt`.
1640+ */
1641+ def advanceCandidates (argTypes : List [Type ]): List [(TermRef , TermRef )] = {
1642+ def strippedType (tp : Type ): Type = tp match {
1643+ case tp : PolyType =>
1644+ val rt = strippedType(tp.resultType)
1645+ if (rt.exists) tp.derivedLambdaType(resType = rt) else rt
1646+ case tp : MethodType =>
1647+ tp.instantiate(argTypes)
1648+ case _ =>
1649+ NoType
1650+ }
1651+ def cloneCandidate (cand : TermRef ): List [(TermRef , TermRef )] = {
1652+ val strippedInfo = strippedType(cand.widen)
1653+ if (strippedInfo.exists) {
1654+ val sym = cand.symbol.asTerm.copy(info = strippedInfo)
1655+ (TermRef (NoPrefix , sym), cand) :: Nil
1656+ }
1657+ else Nil
1658+ }
1659+ overload.println(i " look at more params: ${candidates.head.symbol}: ${candidates.map(_.widen)}%, % with $pt, [ $targs%, %] " )
1660+ candidates.flatMap(cloneCandidate)
1661+ }
1662+
16301663 val found = narrowMostSpecific(candidates)
16311664 if (found.length <= 1 ) found
1632- else {
1633- val noDefaults = alts.filter(! _.symbol.hasDefaultParams)
1634- if (noDefaults.length == 1 ) noDefaults // return unique alternative without default parameters if it exists
1635- else {
1636- val deepPt = pt.deepenProto
1637- if (deepPt ne pt) resolveOverloaded(alts, deepPt, targs)
1638- else alts
1639- }
1665+ else pt match {
1666+ case pt @ FunProto (_, resType : FunProto ) =>
1667+ // try to narrow further with snd argument list
1668+ val advanced = advanceCandidates(pt.typedArgs.tpes)
1669+ resolveOverloaded(advanced.map(_._1), resType, Nil ) // resolve with candidates where first params are stripped
1670+ .map(advanced.toMap) // map surviving result(s) back to original candidates
1671+ case _ =>
1672+ val noDefaults = alts.filter(! _.symbol.hasDefaultParams)
1673+ if (noDefaults.length == 1 ) noDefaults // return unique alternative without default parameters if it exists
1674+ else {
1675+ val deepPt = pt.deepenProto
1676+ if (deepPt ne pt) resolveOverloaded(alts, deepPt, targs)
1677+ else alts
1678+ }
16401679 }
16411680 }
16421681
0 commit comments