Skip to content

Commit

Permalink
Make priority change warning messages stable
Browse files Browse the repository at this point in the history
Make priority change warning messages stable under different orders of eligible.
We now always report the previously chosen alternative first and the new one second.
  • Loading branch information
odersky committed Aug 6, 2024
1 parent f45085a commit c94ffac
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 36 deletions.
62 changes: 30 additions & 32 deletions compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1310,9 +1310,6 @@ trait Implicits:
// message if one of the critical candidates is part of the result of the implicit search.
val priorityChangeWarnings = mutable.ListBuffer[(/*critical:*/ List[TermRef], Message)]()

def isWarnPriorityChangeVersion(sv: SourceVersion): Boolean =
sv.stable == SourceVersion.`3.6` || sv == SourceVersion.`3.7-migration`

/** Compare `alt1` with `alt2` to determine which one should be chosen.
*
* @return a number > 0 if `alt1` is preferred over `alt2`
Expand All @@ -1337,37 +1334,38 @@ trait Implicits:
else
val cmp = comp(using searchContext())
val sv = Feature.sourceVersion
if isWarnPriorityChangeVersion(sv) then
val isLastOldVersion = sv.stable == SourceVersion.`3.6`
val isMigratingVersion = sv == SourceVersion.`3.7-migration`
if isLastOldVersion || isMigratingVersion then
val prev = comp(using searchContext().addMode(Mode.OldImplicitResolution))
if disambiguate && cmp != prev then
def warn(msg: Message) =
val critical = alt1.ref :: alt2.ref :: Nil
priorityChangeWarnings += ((critical, msg))
implicits.println(i"PRIORITY CHANGE ${alt1.ref}, ${alt2.ref}, $disambiguate")
def choice(c: Int) = c match
case -1 => "the second alternative"
case 1 => "the first alternative"
case _ => "none - it's ambiguous"
if sv.stable == SourceVersion.`3.6` then
warn(
em"""Given search preference for $pt between alternatives
| ${alt1.ref}
|and
| ${alt2.ref}
|will change.
|Current choice : ${choice(prev)}
|New choice from Scala 3.7: ${choice(cmp)}""")
prev
else
warn(
em"""Given search preference for $pt between alternatives
| ${alt1.ref}
|and
| ${alt2.ref}
|has changed.
|Previous choice : ${choice(prev)}
|New choice from Scala 3.7: ${choice(cmp)}""")
cmp
implicits.println(i"PRIORITY CHANGE ${alt1.ref}, ${alt2.ref}")
val (loser, winner) =
prev match
case 1 => (alt1, alt2)
case -1 => (alt2, alt1)
case 0 =>
cmp match
case 1 => (alt2, alt1)
case -1 => (alt1, alt2)
def choice(nth: String, c: Int) =
if c == 0 then "none - it's ambiguous"
else s"the $nth alternative"
val (change, whichChoice) =
if isLastOldVersion
then ("will change", "Current choice ")
else ("has changed", "Previous choice")
val msg =
em"""Given search preference for $pt between alternatives
| ${loser.ref}
|and
| ${winner.ref}
|$change.
|$whichChoice : ${choice("first", prev)}
|New choice from Scala 3.7: ${choice("second", cmp)}"""
val critical = alt1.ref :: alt2.ref :: Nil
priorityChangeWarnings += ((critical, msg))
if isLastOldVersion then prev else cmp
else if cmp != prev then
0 // When ranking, we retain a candidate if it is retained in either version.
else cmp
Expand Down
8 changes: 4 additions & 4 deletions tests/neg/given-triangle.check
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
|Ambiguous given instances: both given instance given_B and given instance given_C match type A of parameter a of method f
|
|Note: Given search preference for A between alternatives
| (given_A : A)
|and
| (given_B : B)
|and
| (given_A : A)
|will change.
|Current choice : the second alternative
|New choice from Scala 3.7: the first alternative
|Current choice : the first alternative
|New choice from Scala 3.7: the second alternative
20 changes: 20 additions & 0 deletions tests/warn/i15264.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- Warning: tests/warn/i15264.scala:48:26 ------------------------------------------------------------------------------
48 | val a = summon[A[Int]] // warn
| ^
| Given search preference for repro.A[Int] between alternatives
| (repro.exports.given_C_V : [V](using x$1: priority.Prio0): repro.C[V])
| and
| (repro.exports.given_A_V : [V](using x$1: priority.Prio2): repro.A[V])
| has changed.
| Previous choice : the first alternative
| New choice from Scala 3.7: the second alternative
-- Warning: tests/warn/i15264.scala:55:29 ------------------------------------------------------------------------------
55 | val a = summon[A[Q[Int]]] // warn
| ^
| Given search preference for repro.A[repro.Q[Int]] between alternatives
| (repro.qcontext.gbq : [V](using p1: priority.Prio1)(using b: repro.B[V]): repro.B[repro.Q[V]])
| and
| (repro.qcontext.gaq : [V](using p2: priority.Prio2)(using a: repro.A[V]): repro.A[repro.Q[V]])
| has changed.
| Previous choice : the first alternative
| New choice from Scala 3.7: the second alternative

0 comments on commit c94ffac

Please sign in to comment.