Skip to content

Commit c3692ee

Browse files
committed
Detect case where two alternatives are the same after widening ExprTypes
In implicit or extension method search we might get two alternatives that are different but that point to the same singleton type after widening ExprTypes. In that case we can arbitrarily pick one of them instead of declaring an ambiguity. Fixes #18768
1 parent 38559d7 commit c3692ee

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,14 +1780,21 @@ trait Applications extends Compatibility {
17801780
def winsType2 = isAsSpecific(alt2, tp2, alt1, tp1)
17811781

17821782
overload.println(i"compare($alt1, $alt2)? $tp1 $tp2 $ownerScore $winsType1 $winsType2")
1783-
if (ownerScore == 1)
1784-
if (winsType1 || !winsType2) 1 else 0
1785-
else if (ownerScore == -1)
1786-
if (winsType2 || !winsType1) -1 else 0
1787-
else if (winsType1)
1788-
if (winsType2) 0 else 1
1783+
if winsType1 && winsType2
1784+
&& alt1.widenExpr =:= alt2.widenExpr
1785+
&& alt1.widenExpr.isStable
1786+
then
1787+
// alternatives are the same after following ExprTypes, pick one of them
1788+
// (prefer the one that is not a method, but that's arbitrary).
1789+
if alt1.widenExpr =:= alt2 then -1 else 1
1790+
else if ownerScore == 1 then
1791+
if winsType1 || !winsType2 then 1 else 0
1792+
else if ownerScore == -1 then
1793+
if winsType2 || !winsType1 then -1 else 0
1794+
else if winsType1 then
1795+
if winsType2 then 0 else 1
17891796
else
1790-
if (winsType2) -1 else 0
1797+
if winsType2 then -1 else 0
17911798
}
17921799

17931800
if alt1.symbol.is(ConstructorProxy) && !alt2.symbol.is(ConstructorProxy) then -1

tests/pos/i18768.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
object Module:
2+
object Exportee:
3+
4+
opaque type Id = Long
5+
6+
def apply(): Id = ???
7+
8+
extension (e: Id)
9+
def updated: Id = ???
10+
11+
12+
object Client:
13+
export Module.*
14+
val x = Exportee().updated

0 commit comments

Comments
 (0)