Skip to content

Commit 6cb4b32

Browse files
committed
Avoid useless warnings about priority change in implicit search
Warn about priority change in implicit search only if one of the participating candidates appears in the final result. It could be that we have an priority change between two ranked candidates that both are superseded by the result of the implicit search. In this case, no warning needs to be reported.
1 parent 7bdeb0b commit 6cb4b32

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

compiler/src/dotty/tools/dotc/typer/Implicits.scala

+26-6
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,12 @@ object Implicits:
419419
sealed abstract class SearchResult extends Showable {
420420
def tree: Tree
421421
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+
422428
def recoverWith(other: SearchFailure => SearchResult): SearchResult = this match {
423429
case _: SearchSuccess => this
424430
case fail: SearchFailure => other(fail)
@@ -434,13 +440,17 @@ object Implicits:
434440
* @param tstate The typer state to be committed if this alternative is chosen
435441
*/
436442
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
438445

439446
/** A failed search */
440447
case class SearchFailure(tree: Tree) extends SearchResult {
441448
require(tree.tpe.isInstanceOf[SearchFailureType], s"unexpected type for ${tree}")
442449
final def isAmbiguous: Boolean = tree.tpe.isInstanceOf[AmbiguousImplicits | TooUnspecific]
443450
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
444454
}
445455

446456
object SearchFailure {
@@ -1290,6 +1300,11 @@ trait Implicits:
12901300
/** Search a list of eligible implicit references */
12911301
private def searchImplicit(eligible: List[Candidate], contextual: Boolean): SearchResult =
12921302

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+
12931308
/** Compare `alt1` with `alt2` to determine which one should be chosen.
12941309
*
12951310
* @return a number > 0 if `alt1` is preferred over `alt2`
@@ -1306,6 +1321,8 @@ trait Implicits:
13061321
*/
13071322
def compareAlternatives(alt1: RefAndLevel, alt2: RefAndLevel): Int =
13081323
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)
13091326
if alt1.ref eq alt2.ref then 0
13101327
else if alt1.level != alt2.level then alt1.level - alt2.level
13111328
else
@@ -1319,16 +1336,16 @@ trait Implicits:
13191336
case 1 => "the first alternative"
13201337
case _ => "none - it's ambiguous"
13211338
if sv.stable == SourceVersion.`3.5` then
1322-
report.warning(
1339+
warn(
13231340
em"""Given search preference for $pt between alternatives ${alt1.ref} and ${alt2.ref} will change
13241341
|Current choice : ${choice(prev)}
1325-
|New choice from Scala 3.6: ${choice(cmp)}""", srcPos)
1342+
|New choice from Scala 3.6: ${choice(cmp)}""")
13261343
prev
13271344
else
1328-
report.warning(
1345+
warn(
13291346
em"""Change in given search preference for $pt between alternatives ${alt1.ref} and ${alt2.ref}
13301347
|Previous choice : ${choice(prev)}
1331-
|New choice from Scala 3.6: ${choice(cmp)}""", srcPos)
1348+
|New choice from Scala 3.6: ${choice(cmp)}""")
13321349
cmp
13331350
else cmp
13341351
else cmp
@@ -1578,7 +1595,10 @@ trait Implicits:
15781595
validateOrdering(ord)
15791596
throw ex
15801597

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
15821602
end searchImplicit
15831603

15841604
def isUnderSpecifiedArgument(tp: Type): Boolean =

0 commit comments

Comments
 (0)