@@ -1369,8 +1369,13 @@ trait Implicits:
1369
1369
|New choice from Scala 3.7: ${choice(cmp)}""" )
1370
1370
cmp
1371
1371
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.
1374
1379
else cmp
1375
1380
end compareAlternatives
1376
1381
@@ -1416,7 +1421,15 @@ trait Implicits:
1416
1421
if diff < 0 then alt2
1417
1422
else if diff > 0 then alt1
1418
1423
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
1420
1433
1421
1434
/** Try to find a best matching implicit term among all the candidates in `pending`.
1422
1435
* @param pending The list of candidates that remain to be tested
@@ -1621,7 +1634,7 @@ trait Implicits:
1621
1634
throw ex
1622
1635
1623
1636
val sorted = sort(eligible)
1624
- val result = sorted match
1637
+ val res = sorted match
1625
1638
case first :: rest =>
1626
1639
val firstIsImplicit = first.ref.symbol.is(Implicit )
1627
1640
if rest.exists(_.ref.symbol.is(Implicit ) != firstIsImplicit) then
@@ -1638,11 +1651,11 @@ trait Implicits:
1638
1651
1639
1652
// Issue all priority change warnings that can affect the result
1640
1653
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(_)) =>
1642
1655
msg
1643
- result match
1644
- case result : SearchFailure =>
1645
- result .reason match
1656
+ res match
1657
+ case res : SearchFailure =>
1658
+ res .reason match
1646
1659
case ambi : AmbiguousImplicits =>
1647
1660
// Make warnings part of error message because otherwise they are suppressed when
1648
1661
// the error is emitted.
@@ -1652,7 +1665,7 @@ trait Implicits:
1652
1665
for msg <- shownWarnings do
1653
1666
report.warning(msg, srcPos)
1654
1667
1655
- result
1668
+ res
1656
1669
end searchImplicit
1657
1670
1658
1671
def isUnderSpecifiedArgument (tp : Type ): Boolean =
0 commit comments