@@ -650,8 +650,8 @@ trait Applications extends Compatibility {
650650 /** Subclass of Application for applicability tests with type arguments and value
651651 * argument trees.
652652 */
653- class ApplicableToTrees (methRef : TermRef , targs : List [ Type ], args : List [Tree ], resultType : Type )(implicit ctx : Context )
654- extends TestApplication (methRef, methRef.widen.appliedTo(targs) , args, resultType) {
653+ class ApplicableToTrees (methRef : TermRef , args : List [Tree ], resultType : Type )(implicit ctx : Context )
654+ extends TestApplication (methRef, methRef.widen, args, resultType) {
655655 def argType (arg : Tree , formal : Type ): Type = normalize(arg.tpe, formal)
656656 def treeToArg (arg : Tree ): Tree = arg
657657 def isVarArg (arg : Tree ): Boolean = tpd.isWildcardStarArg(arg)
@@ -662,7 +662,8 @@ trait Applications extends Compatibility {
662662 /** Subclass of Application for applicability tests with type arguments and value
663663 * argument trees.
664664 */
665- class ApplicableToTreesDirectly (methRef : TermRef , targs : List [Type ], args : List [Tree ], resultType : Type )(implicit ctx : Context ) extends ApplicableToTrees (methRef, targs, args, resultType)(ctx) {
665+ class ApplicableToTreesDirectly (methRef : TermRef , args : List [Tree ], resultType : Type )(implicit ctx : Context )
666+ extends ApplicableToTrees (methRef, args, resultType)(ctx) {
666667 override def argOK (arg : TypedArg , formal : Type ): Boolean =
667668 argType(arg, formal) relaxed_<:< formal.widenExpr
668669 }
@@ -1240,34 +1241,33 @@ trait Applications extends Compatibility {
12401241 def typedUnApply (tree : untpd.UnApply , selType : Type )(implicit ctx : Context ): UnApply =
12411242 throw new UnsupportedOperationException (" cannot type check an UnApply node" )
12421243
1243- /** Is given method reference applicable to type arguments `targs` and argument trees `args`?
1244+ /** Is given method reference applicable to argument trees `args`?
12441245 * @param resultType The expected result type of the application
12451246 */
1246- def isApplicableMethodRef (methRef : TermRef , targs : List [ Type ], args : List [Tree ], resultType : Type , keepConstraint : Boolean )(implicit ctx : Context ): Boolean = {
1247+ def isApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type , keepConstraint : Boolean )(implicit ctx : Context ): Boolean = {
12471248 def isApp (implicit ctx : Context ): Boolean =
1248- new ApplicableToTrees (methRef, targs, args, resultType).success
1249+ new ApplicableToTrees (methRef, args, resultType).success
12491250 if (keepConstraint) isApp else ctx.test(isApp)
12501251 }
12511252
1252- /** Is given method reference applicable to type arguments `targs` and argument trees `args` without inferring views?
1253+ /** Is given method reference applicable to argument trees `args` without inferring views?
12531254 * @param resultType The expected result type of the application
12541255 */
1255- def isDirectlyApplicableMethodRef (methRef : TermRef , targs : List [ Type ], args : List [Tree ], resultType : Type )(implicit ctx : Context ): Boolean =
1256- ctx.test(new ApplicableToTreesDirectly (methRef, targs, args, resultType).success)
1256+ def isDirectlyApplicableMethodRef (methRef : TermRef , args : List [Tree ], resultType : Type )(implicit ctx : Context ): Boolean =
1257+ ctx.test(new ApplicableToTreesDirectly (methRef, args, resultType).success)
12571258
12581259 /** Is given method reference applicable to argument types `args`?
12591260 * @param resultType The expected result type of the application
12601261 */
12611262 def isApplicableMethodRef (methRef : TermRef , args : List [Type ], resultType : Type )(implicit ctx : Context ): Boolean =
12621263 ctx.test(new ApplicableToTypes (methRef, args, resultType).success)
12631264
1264- /** Is given type applicable to type arguments `targs` and argument trees `args`,
1265- * possibly after inserting an `apply`?
1265+ /** Is given type applicable to argument trees `args`, possibly after inserting an `apply`?
12661266 * @param resultType The expected result type of the application
12671267 */
1268- def isApplicableType (tp : Type , targs : List [ Type ], args : List [Tree ], resultType : Type , keepConstraint : Boolean )(implicit ctx : Context ): Boolean =
1269- onMethod(tp, targs.nonEmpty || args.nonEmpty) {
1270- isApplicableMethodRef(_, targs, args, resultType, keepConstraint)
1268+ def isApplicableType (tp : Type , args : List [Tree ], resultType : Type , keepConstraint : Boolean )(implicit ctx : Context ): Boolean =
1269+ onMethod(tp, args.nonEmpty) {
1270+ isApplicableMethodRef(_, args, resultType, keepConstraint)
12711271 }
12721272
12731273 /** Is given type applicable to argument types `args`, possibly after inserting an `apply`?
@@ -1538,13 +1538,11 @@ trait Applications extends Compatibility {
15381538 }
15391539 }
15401540
1541- /** Resolve overloaded alternative `alts`, given expected type `pt` and
1542- * possibly also type argument `targs` that need to be applied to each alternative
1543- * to form the method type.
1541+ /** Resolve overloaded alternative `alts`, given expected type `pt`.
15441542 * Two trials: First, without implicits or SAM conversions enabled. Then,
15451543 * if the first finds no eligible candidates, with implicits and SAM conversions enabled.
15461544 */
1547- def resolveOverloaded (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] = {
1545+ def resolveOverloaded (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] =
15481546 record(" resolveOverloaded" )
15491547
15501548 /** Is `alt` a method or polytype whose result type after the first value parameter
@@ -1590,15 +1588,26 @@ trait Applications extends Compatibility {
15901588 case _ => chosen
15911589 }
15921590
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 {
1591+ def resolve (alts : List [TermRef ]): List [TermRef ] =
1592+ pt match
1593+ case pt : FunProto =>
1594+ if pt.isUsingApply then
1595+ val alts0 = alts.filterConserve { alt =>
1596+ val mt = alt.widen.stripPoly
1597+ mt.isImplicitMethod || mt.isContextualMethod
1598+ }
1599+ if alts0 ne alts then return resolve(alts0)
1600+ else if alts.exists(_.widen.stripPoly.isContextualMethod) then
1601+ return resolveMapped(alts, alt => stripImplicit(alt.widen), pt)
1602+ case _ =>
1603+
1604+ var found = resolveOverloaded1(alts, pt)(using ctx.retractMode(Mode .ImplicitsEnabled ))
1605+ if found.isEmpty && ctx.mode.is(Mode .ImplicitsEnabled ) then
1606+ found = resolveOverloaded1(alts, pt)
1607+ found match
15981608 case alt :: Nil => adaptByResult(alt, alts) :: Nil
15991609 case _ => found
1600- }
1601- }
1610+ end resolve
16021611
16031612 /** Try an apply method, if
16041613 * - the result is applied to value arguments and alternative is not a method, or
@@ -1634,15 +1643,16 @@ trait Applications extends Compatibility {
16341643 resolve(expanded).map(retract)
16351644 }
16361645 else resolve(alts)
1637- }
1646+ end resolveOverloaded
16381647
16391648 /** 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
1649+ * overloading resolution, but does neither result adaptation nor apply insertion.
1650+ * It might be called twice from the public `resolveOverloaded` method, once with
16421651 * implicits and SAM conversions enabled, and once without.
16431652 */
1644- private def resolveOverloaded (alts : List [TermRef ], pt : Type , targs : List [Type ])(implicit ctx : Context ): List [TermRef ] =
1645- record(" resolveOverloaded/2" )
1653+ private def resolveOverloaded1 (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] =
1654+ trace(i " resolve over $alts%, %, pt = $pt" , typr, show = true ) {
1655+ record(" resolveOverloaded1" )
16461656
16471657 def isDetermined (alts : List [TermRef ]) = alts.isEmpty || alts.tail.isEmpty
16481658
@@ -1707,22 +1717,6 @@ trait Applications extends Compatibility {
17071717 case _ => arg
17081718 end normArg
17091719
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-
17261720 val candidates = pt match {
17271721 case pt @ FunProto (args, resultType) =>
17281722 val numArgs = args.length
@@ -1753,25 +1747,16 @@ trait Applications extends Compatibility {
17531747
17541748 def narrowByTrees (alts : List [TermRef ], args : List [Tree ], resultType : Type ): List [TermRef ] = {
17551749 val alts2 = alts.filter(alt =>
1756- isDirectlyApplicableMethodRef(alt, targs, args, resultType)
1750+ isDirectlyApplicableMethodRef(alt, args, resultType)
17571751 )
17581752 if (alts2.isEmpty && ! ctx.isAfterTyper)
17591753 alts.filter(alt =>
1760- isApplicableMethodRef(alt, targs, args, resultType, keepConstraint = false )
1754+ isApplicableMethodRef(alt, args, resultType, keepConstraint = false )
17611755 )
17621756 else
17631757 alts2
17641758 }
17651759
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-
17751760 val alts1 = narrowBySize(alts)
17761761 // ctx.log(i"narrowed by size: ${alts1.map(_.symbol.showDcl)}%, %")
17771762 if isDetermined(alts1) then alts1
@@ -1783,9 +1768,10 @@ trait Applications extends Compatibility {
17831768 pretypeArgs(alts2, pt)
17841769 narrowByTrees(alts2, pt.typedArgs(normArg(alts2, _, _)), resultType)
17851770
1786- case pt @ PolyProto (targs1, pt1) if targs.isEmpty =>
1787- val alts1 = alts.filter(pt.isMatchedBy(_))
1788- resolveOverloaded(alts1, pt1, targs1.tpes)
1771+ case pt @ PolyProto (targs1, pt1) =>
1772+ val alts1 = alts.filter(pt.canInstantiate)
1773+ if isDetermined(alts1) then alts1
1774+ else resolveMapped(alts1, _.widen.appliedTo(targs1.tpes), pt1)
17891775
17901776 case defn.FunctionOf (args, resultType, _, _) =>
17911777 narrowByTypes(alts, args, resultType)
@@ -1842,21 +1828,38 @@ trait Applications extends Compatibility {
18421828 if noCurriedCount == 1 then
18431829 noCurried
18441830 else if noCurriedCount > 1 && noCurriedCount < alts.length then
1845- resolveOverloaded (noCurried, pt, targs )
1831+ resolveOverloaded1 (noCurried, pt)
18461832 else
18471833 // prefer alternatves that match without default parameters
18481834 val noDefaults = alts.filter(! _.symbol.hasDefaultParams)
18491835 val noDefaultsCount = noDefaults.length
18501836 if noDefaultsCount == 1 then
18511837 noDefaults
18521838 else if noDefaultsCount > 1 && noDefaultsCount < alts.length then
1853- resolveOverloaded (noDefaults, pt, targs )
1839+ resolveOverloaded1 (noDefaults, pt)
18541840 else if deepPt ne pt then
18551841 // try again with a deeper known expected type
1856- resolveOverloaded (alts, deepPt, targs )
1842+ resolveOverloaded1 (alts, deepPt)
18571843 else
18581844 candidates
1859- end resolveOverloaded
1845+ }
1846+ end resolveOverloaded1
1847+
1848+ /** Resolve overloading by mapping to a different problem where each alternative's
1849+ * type is mapped with `f`, alternatives with non-existing types are dropped, and the
1850+ * expected type is `pt`. Map the results back to the original alternatives.
1851+ */
1852+ def resolveMapped (alts : List [TermRef ], f : TermRef => Type , pt : Type )(using Context ): List [TermRef ] =
1853+ val reverseMapping = alts.flatMap { alt =>
1854+ val t = f(alt)
1855+ if t.exists then
1856+ Some ((TermRef (NoPrefix , alt.symbol.asTerm.copy(info = t)), alt))
1857+ else
1858+ None
1859+ }
1860+ val mapped = reverseMapping.map(_._1)
1861+ overload.println(i " resolve mapped: $mapped" )
1862+ resolveOverloaded(mapped, pt).map(reverseMapping.toMap)
18601863
18611864 /** Try to typecheck any arguments in `pt` that are function values missing a
18621865 * parameter type. If the formal parameter types corresponding to a closure argument
0 commit comments