Skip to content

Commit e3fa8ea

Browse files
EugeneFlessellesjrd
authored andcommitted
Improve overload resolution
`resolveOverloaded1` starts with `narrowMostSpecific(candidates)` which compares the alternatives based on the 1st argument list. If more than one result if found, we can continue with the 2nd argument list. But we do so with the original candidates, rather than with the result of `narrowMostSpecific`. This can lead to choosing an alternative which is not the most specific, by now disregarding the 1st argument list. In i120053, the 1st pass correctly eliminated the 3rd `def ^^^`, but could not resolve between the 1st two (having the same argument list). The 2nd pass then disregarded this and restarted the comparison based on the 2nd argument list alone, which incorrectly yielded the 3rd option. The change is simply using the initial result of `narrowMostSpecific` in the recursive resolution based on subsequent argument lists. I'm not sure however if the same changes should apply to the rest of the cases attempting further narrowing ?
1 parent b3f113e commit e3fa8ea

File tree

5 files changed

+84
-41
lines changed

5 files changed

+84
-41
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2334,11 +2334,11 @@ trait Applications extends Compatibility {
23342334
deepPt match
23352335
case pt @ FunProto(_, PolyProto(targs, resType)) =>
23362336
// try to narrow further with snd argument list and following type params
2337-
resolveMapped(candidates,
2337+
resolveMapped(found,
23382338
skipParamClause(pt.typedArgs().tpes, targs.tpes), resType)
23392339
case pt @ FunProto(_, resType: FunOrPolyProto) =>
23402340
// try to narrow further with snd argument list
2341-
resolveMapped(candidates,
2341+
resolveMapped(found,
23422342
skipParamClause(pt.typedArgs().tpes, Nil), resType)
23432343
case _ =>
23442344
// prefer alternatives that need no eta expansion

compiler/test/dotc/pos-test-pickling.blacklist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ i7445b.scala
122122
i15525.scala
123123
i19955a.scala
124124
i19955b.scala
125+
i20053.scala
125126
i20053b.scala
126127

127128
# alias types at different levels of dereferencing
@@ -134,4 +135,3 @@ parsercombinators-new-syntax.scala
134135
hylolib-deferred-given
135136
hylolib-cb
136137
hylolib
137-

tests/neg/i10901.check

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,3 @@
1-
-- [E008] Not Found Error: tests/neg/i10901.scala:45:38 ----------------------------------------------------------------
2-
45 | val pos1: Point2D[Int,Double] = x º y // error
3-
| ^^^
4-
| value º is not a member of object BugExp4Point2D.IntT.
5-
| An extension method was tried, but could not be fully constructed:
6-
|
7-
| º(x)
8-
|
9-
| failed with:
10-
|
11-
| Ambiguous overload. The overloaded alternatives of method º in object dsl with types
12-
| [T1, T2]
13-
| (x: BugExp4Point2D.ColumnType[T1])
14-
| (y: BugExp4Point2D.ColumnType[T2])
15-
| (implicit evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
16-
| [T1, T2]
17-
| (x: T1)
18-
| (y: BugExp4Point2D.ColumnType[T2])
19-
| (implicit evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
20-
| both match arguments ((x : BugExp4Point2D.IntT.type))((y : BugExp4Point2D.DoubleT.type))
21-
-- [E008] Not Found Error: tests/neg/i10901.scala:48:38 ----------------------------------------------------------------
22-
48 | val pos4: Point2D[Int,Double] = x º 201.1 // error
23-
| ^^^
24-
|value º is not a member of object BugExp4Point2D.IntT.
25-
|An extension method was tried, but could not be fully constructed:
26-
|
27-
| º(x)
28-
|
29-
| failed with:
30-
|
31-
| Ambiguous overload. The overloaded alternatives of method º in object dsl with types
32-
| [T1, T2]
33-
| (x: BugExp4Point2D.ColumnType[T1])
34-
| (y: T2)(implicit evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
35-
| [T1, T2](x: T1)(y: T2)(implicit evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
36-
| both match arguments ((x : BugExp4Point2D.IntT.type))((201.1d : Double))
371
-- [E008] Not Found Error: tests/neg/i10901.scala:62:16 ----------------------------------------------------------------
382
62 | val y = "abc".foo // error
393
| ^^^^^^^^^

tests/neg/i10901.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ object BugExp4Point2D {
4242
val x = IntT
4343
val y = DoubleT
4444

45-
val pos1: Point2D[Int,Double] = x º y // error
45+
val pos1: Point2D[Int,Double] = x º y // ok
4646
val pos2: Point2D[Int,Double] = 100 º 200.1 // ok
4747
val pos3: Point2D[Int,Double] = 101 º y // ok
48-
val pos4: Point2D[Int,Double] = x º 201.1 // error
48+
val pos4: Point2D[Int,Double] = x º 201.1 // ok
4949

5050
}
5151
}

tests/pos/i20053.scala

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
2+
trait Summon[R, T <: R]:
3+
type Out
4+
object Summon:
5+
given [R, T <: R]: Summon[R, T] with
6+
type Out = R
7+
8+
sealed class Modifier[+A, +P]
9+
type ModifierAny = Modifier[Any, Any]
10+
sealed trait ISCONST[T <: Boolean]
11+
type CONST = ISCONST[true]
12+
13+
trait DFTypeAny
14+
trait DFBits[W <: Int] extends DFTypeAny
15+
trait DFVal[+T <: DFTypeAny, +M <: ModifierAny]
16+
type DFValAny = DFVal[DFTypeAny, ModifierAny]
17+
type DFValTP[+T <: DFTypeAny, +P] = DFVal[T, Modifier[Any, P]]
18+
type DFConstOf[+T <: DFTypeAny] = DFVal[T, Modifier[Any, CONST]]
19+
20+
trait Candidate[R]:
21+
type OutW <: Int
22+
type OutP
23+
object Candidate:
24+
given [W <: Int, P, R <: DFValTP[DFBits[W], P]]: Candidate[R] with
25+
type OutW = W
26+
type OutP = P
27+
28+
extension [L <: DFValAny](lhs: L)(using icL: Candidate[L])
29+
def ^^^[R](rhs: R)(using
30+
icR: Candidate[R]
31+
): DFValTP[DFBits[icL.OutW], icL.OutP | icR.OutP] = ???
32+
def ^^^ : Unit = ???
33+
extension [L](lhs: L)
34+
def ^^^[RW <: Int, RP](
35+
rhs: DFValTP[DFBits[RW], RP]
36+
)(using es: Summon[L, lhs.type])(using
37+
c: Candidate[L]
38+
)(using check: c.OutW =:= c.OutW): DFValTP[DFBits[c.OutW], c.OutP | RP] = ???
39+
40+
val x: DFConstOf[DFBits[8]] = ???
41+
val zzz = x ^^^ x ^^^ x
42+
43+
44+
object Minimized:
45+
trait DFVal[+T <: Int, +P]
46+
47+
trait Summon[R, T <: R]
48+
given [R, T <: R]: Summon[R, T] with {}
49+
50+
trait Candidate[R]:
51+
type OutW <: Int
52+
type OutP
53+
given [W <: Int, P, R <: DFVal[W, P]]: Candidate[R] with
54+
type OutW = W
55+
type OutP = P
56+
57+
extension [L <: DFVal[Int, Any]](lhs: L)(using icL: Candidate[L])
58+
def ^^^[R](rhs: R)
59+
(using icR: Candidate[R])
60+
: DFVal[icL.OutW, icL.OutP | icR.OutP] = ???
61+
def ^^^ : Unit = ???
62+
63+
extension [L](lhs: L)
64+
def ^^^[RW <: Int, RP](rhs: DFVal[RW, RP])
65+
(using es: Summon[L, lhs.type])
66+
(using c: Candidate[L])
67+
(using check: c.OutW =:= c.OutW)
68+
: DFVal[c.OutW, c.OutP | RP] = ???
69+
70+
val x: DFVal[8, true] = ???
71+
val z1 = x ^^^ x // Ok
72+
val z2 = z1 ^^^ x // Ok
73+
val zzz = x ^^^ x ^^^ x // Error before changes
74+
75+
/* Before the changes, when `def ^^^ : Unit = ???` is present,
76+
* all of z1, z2, zzz attempt to use the last `def ^^^`,
77+
* despite it being less specific than the 1st one.
78+
*/
79+
end Minimized

0 commit comments

Comments
 (0)