Skip to content

Commit ff0b6b9

Browse files
committed
Another fix to the ranking logic
1 parent e491c87 commit ff0b6b9

File tree

4 files changed

+84
-9
lines changed

4 files changed

+84
-9
lines changed

Diff for: compiler/src/dotty/tools/dotc/ast/Desugar.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ object desugar {
482482
params.map: param =>
483483
val normFlags = param.mods.flags &~ GivenOrImplicit | (mparam.mods.flags & (GivenOrImplicit))
484484
param.withMods(param.mods.withFlags(normFlags))
485-
.showing(i"ADAPTED PARAM $result ${result.mods.flags} for ${meth.name}")
485+
.showing(i"adapted param $result ${result.mods.flags} for ${meth.name}", Printers.desugar)
486486
else params
487487
(normParams ++ mparams) :: Nil
488488
case mparams :: mparamss1 =>

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -1481,8 +1481,8 @@ trait Implicits:
14811481
// need a candidate better than the two ambiguous alternatives.
14821482
val ambi = fail.reason.asInstanceOf[AmbiguousImplicits]
14831483
healAmbiguous(fail, newCand =>
1484-
compareAlternatives(newCand, ambi.alt1) > 0 &&
1485-
compareAlternatives(newCand, ambi.alt2) > 0)
1484+
compareAlternatives(newCand, ambi.alt1, disambiguate = true) > 0 &&
1485+
compareAlternatives(newCand, ambi.alt2, disambiguate = true) > 0)
14861486
}
14871487
}
14881488
case nil =>
@@ -1621,7 +1621,7 @@ trait Implicits:
16211621
throw ex
16221622

16231623
val sorted = sort(eligible)
1624-
val result = sorted match
1624+
val res = sorted match
16251625
case first :: rest =>
16261626
val firstIsImplicit = first.ref.symbol.is(Implicit)
16271627
if rest.exists(_.ref.symbol.is(Implicit) != firstIsImplicit) then
@@ -1638,11 +1638,11 @@ trait Implicits:
16381638

16391639
// Issue all priority change warnings that can affect the result
16401640
val shownWarnings = priorityChangeWarnings.toList.collect:
1641-
case (critical, msg) if result.found.exists(critical.contains(_)) =>
1641+
case (critical, msg) if res.found.exists(critical.contains(_)) =>
16421642
msg
1643-
result match
1644-
case result: SearchFailure =>
1645-
result.reason match
1643+
res match
1644+
case res: SearchFailure =>
1645+
res.reason match
16461646
case ambi: AmbiguousImplicits =>
16471647
// Make warnings part of error message because otherwise they are suppressed when
16481648
// the error is emitted.
@@ -1652,7 +1652,7 @@ trait Implicits:
16521652
for msg <- shownWarnings do
16531653
report.warning(msg, srcPos)
16541654

1655-
result
1655+
res
16561656
end searchImplicit
16571657

16581658
def isUnderSpecifiedArgument(tp: Type): Boolean =

Diff for: tests/warn/i15264.check

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- Warning: tests/warn/i15264.scala:48:26 ------------------------------------------------------------------------------
2+
48 | val a = summon[A[Int]] // warn
3+
| ^
4+
| Given search preference for repro.A[Int] between alternatives
5+
| (repro.exports.given_A_V : [V](using x$1: priority.Prio2): repro.A[V])
6+
| and
7+
| (repro.exports.given_C_V : [V](using x$1: priority.Prio0): repro.C[V])
8+
| has changed.
9+
| Previous choice : the second alternative
10+
| New choice from Scala 3.7: the first alternative
11+
-- Warning: tests/warn/i15264.scala:55:29 ------------------------------------------------------------------------------
12+
55 | val a = summon[A[Q[Int]]] // warn
13+
| ^
14+
| Given search preference for repro.A[repro.Q[Int]] between alternatives
15+
| (repro.qcontext.gcq : [V](using p0: priority.Prio0)(using c: repro.C[V]): repro.C[repro.Q[V]])
16+
| and
17+
| (repro.qcontext.gaq : [V](using p2: priority.Prio2)(using a: repro.A[V]): repro.A[repro.Q[V]])
18+
| has changed.
19+
| Previous choice : the first alternative
20+
| New choice from Scala 3.7: the second alternative

Diff for: tests/warn/i15264.scala

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import language.`3.7-migration`
2+
object priority:
3+
// lower number = higher priority
4+
class Prio0 extends Prio1
5+
object Prio0 { given Prio0() }
6+
7+
class Prio1 extends Prio2
8+
object Prio1 { given Prio1() }
9+
10+
class Prio2
11+
object Prio2 { given Prio2() }
12+
13+
object repro:
14+
// analogous to cats Eq, Hash, Order:
15+
class A[V]
16+
class B[V] extends A[V]
17+
class C[V] extends A[V]
18+
19+
class Q[V]
20+
21+
object context:
22+
// prios work here, which is cool
23+
given[V](using priority.Prio0): C[V] = new C[V]
24+
given[V](using priority.Prio1): B[V] = new B[V]
25+
given[V](using priority.Prio2): A[V] = new A[V]
26+
27+
object exports:
28+
// so will these exports
29+
export context.given
30+
31+
// if you import these don't import from 'context' above
32+
object qcontext:
33+
// base defs, like what you would get from cats
34+
given ga: A[Int] = new B[Int] // added so that we don't get an ambiguity in test2
35+
given gb: B[Int] = new B[Int]
36+
given gc: C[Int] = new C[Int]
37+
38+
// these seem like they should work but don't
39+
given gcq[V](using p0: priority.Prio0)(using c: C[V]): C[Q[V]] = new C[Q[V]]
40+
given gbq[V](using p1: priority.Prio1)(using b: B[V]): B[Q[V]] = new B[Q[V]]
41+
given gaq[V](using p2: priority.Prio2)(using a: A[V]): A[Q[V]] = new A[Q[V]]
42+
43+
object test1:
44+
import repro.*
45+
import repro.exports.given
46+
47+
// these will work
48+
val a = summon[A[Int]] // warn
49+
50+
51+
object test2:
52+
import repro.*
53+
import repro.qcontext.given
54+
55+
val a = summon[A[Q[Int]]] // warn

0 commit comments

Comments
 (0)