@@ -1544,7 +1544,7 @@ trait Applications extends Compatibility {
1544
1544
* Two trials: First, without implicits or SAM conversions enabled. Then,
1545
1545
* if the first finds no eligible candidates, with implicits and SAM conversions enabled.
1546
1546
*/
1547
- def resolveOverloaded (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] = {
1547
+ def resolveOverloaded (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] =
1548
1548
record(" resolveOverloaded" )
1549
1549
1550
1550
/** Is `alt` a method or polytype whose result type after the first value parameter
@@ -1590,15 +1590,26 @@ trait Applications extends Compatibility {
1590
1590
case _ => chosen
1591
1591
}
1592
1592
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 {
1593
+ def resolve (alts : List [TermRef ]): List [TermRef ] =
1594
+ pt match
1595
+ case pt : FunProto =>
1596
+ if pt.isUsingApply then
1597
+ val alts0 = alts.filterConserve { alt =>
1598
+ val mt = alt.widen.stripPoly
1599
+ mt.isImplicitMethod || mt.isContextualMethod
1600
+ }
1601
+ if alts0 ne alts then return resolve(alts0)
1602
+ else if alts.exists(_.widen.stripPoly.isContextualMethod) then
1603
+ return resolveMapped(alts, alt => stripImplicit(alt.widen), pt)
1604
+ case _ =>
1605
+
1606
+ var found = resolveOverloaded1(alts, pt)(using ctx.retractMode(Mode .ImplicitsEnabled ))
1607
+ if found.isEmpty && ctx.mode.is(Mode .ImplicitsEnabled ) then
1608
+ found = resolveOverloaded1(alts, pt)
1609
+ found match
1598
1610
case alt :: Nil => adaptByResult(alt, alts) :: Nil
1599
1611
case _ => found
1600
- }
1601
- }
1612
+ end resolve
1602
1613
1603
1614
/** Try an apply method, if
1604
1615
* - the result is applied to value arguments and alternative is not a method, or
@@ -1634,15 +1645,16 @@ trait Applications extends Compatibility {
1634
1645
resolve(expanded).map(retract)
1635
1646
}
1636
1647
else resolve(alts)
1637
- }
1648
+ end resolveOverloaded
1638
1649
1639
1650
/** 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
1651
+ * overloading resolution, but does neither result adaptation nor apply insertion.
1652
+ * It might be called twice from the public `resolveOverloaded` method, once with
1642
1653
* implicits and SAM conversions enabled, and once without.
1643
1654
*/
1644
- private def resolveOverloaded (alts : List [TermRef ], pt : Type , targs : List [Type ])(implicit ctx : Context ): List [TermRef ] =
1645
- record(" resolveOverloaded/2" )
1655
+ private def resolveOverloaded1 (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] =
1656
+ trace(i " resolve over $alts%, %, pt = $pt" , typr, show = true ) {
1657
+ record(" resolveOverloaded1" )
1646
1658
1647
1659
def isDetermined (alts : List [TermRef ]) = alts.isEmpty || alts.tail.isEmpty
1648
1660
@@ -1707,22 +1719,6 @@ trait Applications extends Compatibility {
1707
1719
case _ => arg
1708
1720
end normArg
1709
1721
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
-
1726
1722
val candidates = pt match {
1727
1723
case pt @ FunProto (args, resultType) =>
1728
1724
val numArgs = args.length
@@ -1753,25 +1749,16 @@ trait Applications extends Compatibility {
1753
1749
1754
1750
def narrowByTrees (alts : List [TermRef ], args : List [Tree ], resultType : Type ): List [TermRef ] = {
1755
1751
val alts2 = alts.filter(alt =>
1756
- isDirectlyApplicableMethodRef(alt, targs , args, resultType)
1752
+ isDirectlyApplicableMethodRef(alt, Nil , args, resultType)
1757
1753
)
1758
1754
if (alts2.isEmpty && ! ctx.isAfterTyper)
1759
1755
alts.filter(alt =>
1760
- isApplicableMethodRef(alt, targs , args, resultType, keepConstraint = false )
1756
+ isApplicableMethodRef(alt, Nil , args, resultType, keepConstraint = false )
1761
1757
)
1762
1758
else
1763
1759
alts2
1764
1760
}
1765
1761
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
-
1775
1762
val alts1 = narrowBySize(alts)
1776
1763
// ctx.log(i"narrowed by size: ${alts1.map(_.symbol.showDcl)}%, %")
1777
1764
if isDetermined(alts1) then alts1
@@ -1783,9 +1770,10 @@ trait Applications extends Compatibility {
1783
1770
pretypeArgs(alts2, pt)
1784
1771
narrowByTrees(alts2, pt.typedArgs(normArg(alts2, _, _)), resultType)
1785
1772
1786
- case pt @ PolyProto (targs1, pt1) if targs.isEmpty =>
1787
- val alts1 = alts.filter(pt.isMatchedBy(_))
1788
- resolveOverloaded(alts1, pt1, targs1.tpes)
1773
+ case pt @ PolyProto (targs1, pt1) =>
1774
+ val alts1 = alts.filter(pt.canInstantiate)
1775
+ if isDetermined(alts1) then alts1
1776
+ else resolveMapped(alts1, _.widen.appliedTo(targs1.tpes), pt1)
1789
1777
1790
1778
case defn.FunctionOf (args, resultType, _, _) =>
1791
1779
narrowByTypes(alts, args, resultType)
@@ -1842,21 +1830,38 @@ trait Applications extends Compatibility {
1842
1830
if noCurriedCount == 1 then
1843
1831
noCurried
1844
1832
else if noCurriedCount > 1 && noCurriedCount < alts.length then
1845
- resolveOverloaded (noCurried, pt, targs )
1833
+ resolveOverloaded1 (noCurried, pt)
1846
1834
else
1847
1835
// prefer alternatves that match without default parameters
1848
1836
val noDefaults = alts.filter(! _.symbol.hasDefaultParams)
1849
1837
val noDefaultsCount = noDefaults.length
1850
1838
if noDefaultsCount == 1 then
1851
1839
noDefaults
1852
1840
else if noDefaultsCount > 1 && noDefaultsCount < alts.length then
1853
- resolveOverloaded (noDefaults, pt, targs )
1841
+ resolveOverloaded1 (noDefaults, pt)
1854
1842
else if deepPt ne pt then
1855
1843
// try again with a deeper known expected type
1856
- resolveOverloaded (alts, deepPt, targs )
1844
+ resolveOverloaded1 (alts, deepPt)
1857
1845
else
1858
1846
candidates
1859
- end resolveOverloaded
1847
+ }
1848
+ end resolveOverloaded1
1849
+
1850
+ /** Resolve overloading by mapping to a different problem where each alternative's
1851
+ * type is mapped with `f`, alternatives with non-existing types are dropped, and the
1852
+ * expected type is `pt`. Map the results back to the original alternatives.
1853
+ */
1854
+ def resolveMapped (alts : List [TermRef ], f : TermRef => Type , pt : Type )(using Context ): List [TermRef ] =
1855
+ val reverseMapping = alts.flatMap { alt =>
1856
+ val t = f(alt)
1857
+ if t.exists then
1858
+ Some ((TermRef (NoPrefix , alt.symbol.asTerm.copy(info = t)), alt))
1859
+ else
1860
+ None
1861
+ }
1862
+ val mapped = reverseMapping.map(_._1)
1863
+ overload.println(i " resolve mapped: $mapped" )
1864
+ resolveOverloaded(mapped, pt).map(reverseMapping.toMap)
1860
1865
1861
1866
/** Try to typecheck any arguments in `pt` that are function values missing a
1862
1867
* parameter type. If the formal parameter types corresponding to a closure argument
0 commit comments