Skip to content

Commit 39c49ad

Browse files
committed
Fix ownerscore disambiguation
1 parent e1cc065 commit 39c49ad

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

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

+13-7
Original file line numberDiff line numberDiff line change
@@ -1975,13 +1975,19 @@ trait Applications extends Compatibility {
19751975
// alternatives are the same after following ExprTypes, pick one of them
19761976
// (prefer the one that is not a method, but that's arbitrary).
19771977
if alt1.widenExpr =:= alt2 then -1 else 1
1978-
else ownerScore match
1979-
case 1 => if winsType1 || !winsType2 then 1 else 0
1980-
case -1 => if winsType2 || !winsType1 then -1 else 0
1981-
case 0 =>
1982-
if winsType1 != winsType2 then if winsType1 then 1 else -1
1983-
else if alt1.symbol == alt2.symbol then comparePrefixes
1984-
else 0
1978+
else
1979+
// For implicit resolution, take ownerscore as more significant than type resolution
1980+
// Reason: People use owner hierarchies to explicitly prioritize, we should not
1981+
// break that by changing implicit priority of types. On the other hand we do want
1982+
// to comparePrefixes if there is a draw; StringFormaterTest breaks if we don't do that.
1983+
def drawOrOwner = if preferGeneral then ownerScore else 0
1984+
ownerScore match
1985+
case 1 => if winsType1 || !winsType2 then 1 else drawOrOwner
1986+
case -1 => if winsType2 || !winsType1 then -1 else drawOrOwner
1987+
case 0 =>
1988+
if winsType1 != winsType2 then if winsType1 then 1 else -1
1989+
else if alt1.symbol == alt2.symbol then comparePrefixes
1990+
else 0
19851991
end compareWithTypes
19861992

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

Diff for: tests/pos/given-priority.scala

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* These tests show various mechanisms available for implicit prioritization.
2+
*/
3+
import language.`3.6`
4+
5+
class A // The type for which we infer terms below
6+
class B extends A
7+
8+
/* First, two schemes that require a pre-planned architecture for how and
9+
* where given instances are defined.
10+
*
11+
* Traditional scheme: prioritize with location in class hierarchy
12+
*/
13+
class LowPriorityImplicits:
14+
given g1: A()
15+
16+
object NormalImplicits extends LowPriorityImplicits:
17+
given g2: B()
18+
19+
def test1 =
20+
import NormalImplicits.given
21+
val x = summon[A]
22+
val _: B = x
23+
val y = summon[B]
24+
val _: B = y

0 commit comments

Comments
 (0)