Skip to content

Commit 822eec6

Browse files
Do prefix comparison also in comparison including implicit parameters
1 parent 8eeee0b commit 822eec6

File tree

2 files changed

+24
-23
lines changed

2 files changed

+24
-23
lines changed

Diff for: compiler/src/dotty/tools/dotc/typer/Applications.scala

+18-20
Original file line numberDiff line numberDiff line change
@@ -1831,18 +1831,20 @@ trait Applications extends Compatibility {
18311831
*
18321832
* In this case `b.M` would be regarded as more specific than `a.M`.
18331833
*/
1834-
def comparePrefixes(pre1: Type, pre2: Type) =
1834+
def comparePrefixes =
1835+
val pre1 = widenPrefix(alt1)
1836+
val pre2 = widenPrefix(alt2)
18351837
val winsPrefix1 = isAsSpecificValueType(pre1, pre2)
18361838
val winsPrefix2 = isAsSpecificValueType(pre2, pre1)
18371839
if winsPrefix1 == winsPrefix2 then 0
18381840
else if winsPrefix1 then 1
18391841
else -1
18401842

1841-
def compareWithTypes(tp1: Type, tp2: Type) = {
1843+
def compareWithTypes(tp1: Type, tp2: Type) =
18421844
val ownerScore = compareOwner(alt1.symbol.maybeOwner, alt2.symbol.maybeOwner)
18431845

1844-
def winsType1 = isAsSpecific(alt1, tp1, alt2, tp2)
1845-
def winsType2 = isAsSpecific(alt2, tp2, alt1, tp1)
1846+
val winsType1 = isAsSpecific(alt1, tp1, alt2, tp2)
1847+
val winsType2 = isAsSpecific(alt2, tp2, alt1, tp1)
18461848

18471849
overload.println(i"compare($alt1, $alt2)? $tp1 $tp2 $ownerScore $winsType1 $winsType2")
18481850
if winsType1 && winsType2
@@ -1851,15 +1853,14 @@ trait Applications extends Compatibility {
18511853
// alternatives are the same after following ExprTypes, pick one of them
18521854
// (prefer the one that is not a method, but that's arbitrary).
18531855
if alt1.widenExpr =:= alt2 then -1 else 1
1854-
else if ownerScore == 1 then
1855-
if winsType1 || !winsType2 then 1 else 0
1856-
else if ownerScore == -1 then
1857-
if winsType2 || !winsType1 then -1 else 0
1858-
else if winsType1 then
1859-
if winsType2 then 0 else 1
1860-
else
1861-
if winsType2 then -1 else 0
1862-
}
1856+
else ownerScore match
1857+
case 1 => if winsType1 || !winsType2 then 1 else 0
1858+
case -1 => if winsType2 || !winsType1 then -1 else 0
1859+
case 0 =>
1860+
if winsType1 != winsType2 then if winsType1 then 1 else -1
1861+
else if alt1.symbol == alt2.symbol then comparePrefixes
1862+
else 0
1863+
end compareWithTypes
18631864

18641865
if alt1.symbol.is(ConstructorProxy) && !alt2.symbol.is(ConstructorProxy) then -1
18651866
else if alt2.symbol.is(ConstructorProxy) && !alt1.symbol.is(ConstructorProxy) then 1
@@ -1870,14 +1871,11 @@ trait Applications extends Compatibility {
18701871
val strippedType2 = stripImplicit(fullType2)
18711872

18721873
val result = compareWithTypes(strippedType1, strippedType2)
1873-
if result != 0 then result
1874-
else if strippedType1 eq fullType1 then
1875-
if strippedType2 eq fullType2 then
1876-
if alt1.symbol != alt2.symbol then 0 // no implicits either side: it's a draw ...
1877-
else comparePrefixes( // ... unless the symbol is the same, in which case
1878-
widenPrefix(alt1), widenPrefix(alt2)) // we compare prefixes
1874+
if (result != 0) result
1875+
else if (strippedType1 eq fullType1)
1876+
if (strippedType2 eq fullType2) 0 // no implicits either side: its' a draw
18791877
else 1 // prefer 1st alternative with no implicits
1880-
else if strippedType2 eq fullType2 then -1 // prefer 2nd alternative with no implicits
1878+
else if (strippedType2 eq fullType2) -1 // prefer 2nd alternative with no implicits
18811879
else compareWithTypes(fullType1, fullType2) // continue by comparing implicits parameters
18821880
}
18831881
end compare

Diff for: tests/pos/implicit-prefix-disambiguation.scala

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1+
12
class I[X]
3+
class J[X]
24

35
trait A:
46
given I[B] = ???
7+
given (using I[B]): J[B] = ???
58
object A extends A
69

710
trait B extends A
811
object B extends B
912

1013
//import B.given, A.given
1114

12-
def Test = summon[I[B]]
13-
14-
15+
def Test =
16+
summon[I[B]]
17+
summon[J[B]]

0 commit comments

Comments
 (0)