@@ -1369,8 +1369,13 @@ trait Implicits:
13691369 |New choice from Scala 3.7: ${choice(cmp)}""" )
13701370 cmp
13711371 else cmp max prev
1372- // When ranking, we keep the better of cmp and prev, which ends up retaining a candidate
1373- // if it is retained in either version.
1372+ // When ranking, alt1 is always the new candidate and alt2 is the
1373+ // solution found previously. We keep the candidate if the outcome is 0
1374+ // (ambiguous) or 1 (first wins). Or, when ranking in healImplicit we keep the
1375+ // candidate only if the outcome is 1. In both cases, keeping the better
1376+ // of `cmp` and `prev` means we keep candidates that could match
1377+ // in either scheme. This means that subsequent disambiguation
1378+ // comparisons will record a warning if cmp != prev.
13741379 else cmp
13751380 end compareAlternatives
13761381
@@ -1416,7 +1421,15 @@ trait Implicits:
14161421 if diff < 0 then alt2
14171422 else if diff > 0 then alt1
14181423 else SearchFailure (new AmbiguousImplicits (alt1, alt2, pt, argument), span)
1419- case _ : SearchFailure => alt2
1424+ case fail : SearchFailure =>
1425+ fail.reason match
1426+ case ambi : AmbiguousImplicits =>
1427+ if compareAlternatives(ambi.alt1, alt2) < 0 &&
1428+ compareAlternatives(ambi.alt2, alt2) < 0
1429+ then alt2
1430+ else alt1
1431+ case _ =>
1432+ alt2
14201433
14211434 /** Try to find a best matching implicit term among all the candidates in `pending`.
14221435 * @param pending The list of candidates that remain to be tested
@@ -1621,7 +1634,7 @@ trait Implicits:
16211634 throw ex
16221635
16231636 val sorted = sort(eligible)
1624- val result = sorted match
1637+ val res = sorted match
16251638 case first :: rest =>
16261639 val firstIsImplicit = first.ref.symbol.is(Implicit )
16271640 if rest.exists(_.ref.symbol.is(Implicit ) != firstIsImplicit) then
@@ -1638,11 +1651,11 @@ trait Implicits:
16381651
16391652 // Issue all priority change warnings that can affect the result
16401653 val shownWarnings = priorityChangeWarnings.toList.collect:
1641- case (critical, msg) if result .found.exists(critical.contains(_)) =>
1654+ case (critical, msg) if res .found.exists(critical.contains(_)) =>
16421655 msg
1643- result match
1644- case result : SearchFailure =>
1645- result .reason match
1656+ res match
1657+ case res : SearchFailure =>
1658+ res .reason match
16461659 case ambi : AmbiguousImplicits =>
16471660 // Make warnings part of error message because otherwise they are suppressed when
16481661 // the error is emitted.
@@ -1652,7 +1665,7 @@ trait Implicits:
16521665 for msg <- shownWarnings do
16531666 report.warning(msg, srcPos)
16541667
1655- result
1668+ res
16561669 end searchImplicit
16571670
16581671 def isUnderSpecifiedArgument (tp : Type ): Boolean =
0 commit comments