@@ -419,6 +419,12 @@ object Implicits:
419
419
sealed abstract class SearchResult extends Showable {
420
420
def tree : Tree
421
421
def toText (printer : Printer ): Text = printer.toText(this )
422
+
423
+ /** The references that were found, there can be two of them in the case
424
+ * of an AmbiguousImplicits failure
425
+ */
426
+ def found : List [TermRef ]
427
+
422
428
def recoverWith (other : SearchFailure => SearchResult ): SearchResult = this match {
423
429
case _ : SearchSuccess => this
424
430
case fail : SearchFailure => other(fail)
@@ -434,13 +440,17 @@ object Implicits:
434
440
* @param tstate The typer state to be committed if this alternative is chosen
435
441
*/
436
442
case class SearchSuccess (tree : Tree , ref : TermRef , level : Int , isExtension : Boolean = false )(val tstate : TyperState , val gstate : GadtConstraint )
437
- extends SearchResult with RefAndLevel with Showable
443
+ extends SearchResult with RefAndLevel with Showable :
444
+ final def found = ref :: Nil
438
445
439
446
/** A failed search */
440
447
case class SearchFailure (tree : Tree ) extends SearchResult {
441
448
require(tree.tpe.isInstanceOf [SearchFailureType ], s " unexpected type for ${tree}" )
442
449
final def isAmbiguous : Boolean = tree.tpe.isInstanceOf [AmbiguousImplicits | TooUnspecific ]
443
450
final def reason : SearchFailureType = tree.tpe.asInstanceOf [SearchFailureType ]
451
+ final def found = tree.tpe match
452
+ case tpe : AmbiguousImplicits => tpe.alt1.ref :: tpe.alt2.ref :: Nil
453
+ case _ => Nil
444
454
}
445
455
446
456
object SearchFailure {
@@ -1290,6 +1300,11 @@ trait Implicits:
1290
1300
/** Search a list of eligible implicit references */
1291
1301
private def searchImplicit (eligible : List [Candidate ], contextual : Boolean ): SearchResult =
1292
1302
1303
+ // A map that associates a priority change warning (between -source 3.4 and 3.6)
1304
+ // with a candidate ref mentioned in the warning. We report the associated
1305
+ // message if the candidate ref is part of the result of the implicit search
1306
+ var priorityChangeWarnings = mutable.ListBuffer [(TermRef , Message )]()
1307
+
1293
1308
/** Compare `alt1` with `alt2` to determine which one should be chosen.
1294
1309
*
1295
1310
* @return a number > 0 if `alt1` is preferred over `alt2`
@@ -1306,6 +1321,8 @@ trait Implicits:
1306
1321
*/
1307
1322
def compareAlternatives (alt1 : RefAndLevel , alt2 : RefAndLevel ): Int =
1308
1323
def comp (using Context ) = explore(compare(alt1.ref, alt2.ref, preferGeneral = true ))
1324
+ def warn (msg : Message ) =
1325
+ priorityChangeWarnings += (alt1.ref -> msg) += (alt2.ref -> msg)
1309
1326
if alt1.ref eq alt2.ref then 0
1310
1327
else if alt1.level != alt2.level then alt1.level - alt2.level
1311
1328
else
@@ -1319,16 +1336,16 @@ trait Implicits:
1319
1336
case 1 => " the first alternative"
1320
1337
case _ => " none - it's ambiguous"
1321
1338
if sv.stable == SourceVersion .`3.5` then
1322
- report.warning (
1339
+ warn (
1323
1340
em """ Given search preference for $pt between alternatives ${alt1.ref} and ${alt2.ref} will change
1324
1341
|Current choice : ${choice(prev)}
1325
- |New choice from Scala 3.6: ${choice(cmp)}""" , srcPos )
1342
+ |New choice from Scala 3.6: ${choice(cmp)}""" )
1326
1343
prev
1327
1344
else
1328
- report.warning (
1345
+ warn (
1329
1346
em """ Change in given search preference for $pt between alternatives ${alt1.ref} and ${alt2.ref}
1330
1347
|Previous choice : ${choice(prev)}
1331
- |New choice from Scala 3.6: ${choice(cmp)}""" , srcPos )
1348
+ |New choice from Scala 3.6: ${choice(cmp)}""" )
1332
1349
cmp
1333
1350
else cmp
1334
1351
else cmp
@@ -1578,7 +1595,10 @@ trait Implicits:
1578
1595
validateOrdering(ord)
1579
1596
throw ex
1580
1597
1581
- rank(sort(eligible), NoMatchingImplicitsFailure , Nil )
1598
+ val result = rank(sort(eligible), NoMatchingImplicitsFailure , Nil )
1599
+ for (ref, msg) <- priorityChangeWarnings do
1600
+ if result.found.contains(ref) then report.warning(msg, srcPos)
1601
+ result
1582
1602
end searchImplicit
1583
1603
1584
1604
def isUnderSpecifiedArgument (tp : Type ): Boolean =
0 commit comments