Skip to content

Commit f8c70ee

Browse files
committed
Fix #7793: Handle using parameters in resolveOverloaded
resolvePverloaded now takes into account whether arguments are using clauses or regular arguments.
1 parent b5ef0ee commit f8c70ee

File tree

3 files changed

+47
-29
lines changed

3 files changed

+47
-29
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3311,7 +3311,6 @@ object Types {
33113311
companion.eq(ContextualMethodType) ||
33123312
companion.eq(ErasedContextualMethodType)
33133313

3314-
33153314
def computeSignature(implicit ctx: Context): Signature = {
33163315
val params = if (isErasedMethod) Nil else paramInfos
33173316
resultSignature.prependTermParams(params, isJavaMethod)

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

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,16 @@ trait Applications extends Compatibility {
12991299
}
13001300
}
13011301

1302+
/** Drop any implicit parameter section */
1303+
def stripImplicit(tp: Type)(using Context): Type = tp match {
1304+
case mt: MethodType if mt.isImplicitMethod =>
1305+
stripImplicit(resultTypeApprox(mt))
1306+
case pt: PolyType =>
1307+
pt.derivedLambdaType(pt.paramNames, pt.paramInfos, stripImplicit(pt.resultType))
1308+
case _ =>
1309+
tp
1310+
}
1311+
13021312
/** Compare owner inheritance level.
13031313
* @param sym1 The first owner
13041314
* @param sym2 The second owner
@@ -1466,16 +1476,6 @@ trait Applications extends Compatibility {
14661476
else tp
14671477
}
14681478

1469-
/** Drop any implicit parameter section */
1470-
def stripImplicit(tp: Type): Type = tp match {
1471-
case mt: MethodType if mt.isImplicitMethod =>
1472-
stripImplicit(resultTypeApprox(mt))
1473-
case pt: PolyType =>
1474-
pt.derivedLambdaType(pt.paramNames, pt.paramInfos, stripImplicit(pt.resultType))
1475-
case _ =>
1476-
tp
1477-
}
1478-
14791479
def compareWithTypes(tp1: Type, tp2: Type) = {
14801480
val ownerScore = compareOwner(alt1.symbol.maybeOwner, alt2.symbol.maybeOwner)
14811481
def winsType1 = isAsSpecific(alt1, tp1, alt2, tp2)
@@ -1707,6 +1707,22 @@ trait Applications extends Compatibility {
17071707
case _ => arg
17081708
end normArg
17091709

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+
17101726
val candidates = pt match {
17111727
case pt @ FunProto(args, resultType) =>
17121728
val numArgs = args.length
@@ -1747,6 +1763,15 @@ trait Applications extends Compatibility {
17471763
alts2
17481764
}
17491765

1766+
if pt.isGivenApply 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+
17501775
val alts1 = narrowBySize(alts)
17511776
//ctx.log(i"narrowed by size: ${alts1.map(_.symbol.showDcl)}%, %")
17521777
if isDetermined(alts1) then alts1
@@ -1783,34 +1808,19 @@ trait Applications extends Compatibility {
17831808
else compat
17841809
}
17851810

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.
1789-
*/
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-
18021811
/** The type of alternative `alt` after instantiating its first parameter
18031812
* clause with `argTypes`.
18041813
*/
18051814
def skipParamClause(argTypes: List[Type])(alt: TermRef): Type =
1806-
def skip(tp: Type): Type = tp match
1815+
def skip(tp: Type): Type = tp match {
18071816
case tp: PolyType =>
18081817
val rt = skip(tp.resultType)
1809-
if rt.exists then tp.derivedLambdaType(resType = rt) else rt
1818+
if (rt.exists) tp.derivedLambdaType(resType = rt) else rt
18101819
case tp: MethodType =>
18111820
tp.instantiate(argTypes)
18121821
case _ =>
18131822
NoType
1823+
}
18141824
skip(alt.widen)
18151825

18161826
def resultIsMethod(tp: Type): Boolean = tp.widen.stripPoly match

tests/pos/i7793.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
trait Foo:
2+
def g(f: Int => Int): Int = 1
3+
def g(using String)(f: Int => String): String = "2"
4+
5+
@main def Test =
6+
val m: Foo = ???
7+
given String = "foo"
8+
m.g(x => "2")
9+
m.g(using summon[String])(x => "2")

0 commit comments

Comments
 (0)