@@ -247,11 +247,9 @@ object Implicits:
247247 candidates += Candidate (ref, ckind, level)
248248
249249 if considerExtension then
250- val tryExtension = tryCandidate(extensionOnly = true )
251- companionRefs.foreach(tryExtension)
250+ companionRefs.foreach(tryCandidate(extensionOnly = true ))
252251 if refs.nonEmpty then
253- val tryGiven = tryCandidate(extensionOnly = false )
254- refs.foreach(tryGiven)
252+ refs.foreach(tryCandidate(extensionOnly = false ))
255253 candidates.toList
256254 }
257255 }
@@ -488,9 +486,10 @@ object Implicits:
488486
489487 class DivergingImplicit (ref : TermRef ,
490488 val expectedType : Type ,
491- val argument : Tree ) extends SearchFailureType {
489+ val argument : Tree ,
490+ addendum : => String = " " ) extends SearchFailureType {
492491 def explanation (using Context ): String =
493- em " ${err.refStr(ref)} produces a diverging implicit search when trying to $qualify"
492+ em " ${err.refStr(ref)} produces a diverging implicit search when trying to $qualify$addendum "
494493 }
495494
496495 class FailedExtension (extApp : Tree , val expectedType : Type ) extends SearchFailureType :
@@ -1101,7 +1100,13 @@ trait Implicits:
11011100 */
11021101 def tryImplicit (cand : Candidate , contextual : Boolean ): SearchResult =
11031102 if checkDivergence(cand) then
1104- SearchFailure (new DivergingImplicit (cand.ref, wideProto, argument))
1103+ val addendum = ctx.searchHistory.disqualifiedType match
1104+ case NoType => " "
1105+ case disTp =>
1106+ em """ .
1107+ |Note that open search type $disTp cannot be re-used as a by-name implicit parameter
1108+ |since it is not fully defined """
1109+ SearchFailure (new DivergingImplicit (cand.ref, wideProto, argument, addendum))
11051110 else {
11061111 val history = ctx.searchHistory.nest(cand, pt)
11071112 val result =
@@ -1371,8 +1376,12 @@ trait Implicits:
13711376 history match
13721377 case prev @ OpenSearch (cand1, tp, outer) =>
13731378 if cand1.ref eq cand.ref then
1379+ def checkFullyDefined =
1380+ val result = isFullyDefined(tp, ForceDegree .failBottom)
1381+ if ! result then prev.disqualified = true
1382+ result
13741383 lazy val wildTp = wildApprox(tp.widenExpr)
1375- if belowByname && (wildTp <:< wildPt) then
1384+ if belowByname && (wildTp <:< wildPt) && checkFullyDefined then
13761385 false
13771386 else if prev.typeSize > ptSize || prev.coveringSet != ptCoveringSet then
13781387 loop(outer, tp.isByName || belowByname)
@@ -1464,6 +1473,15 @@ abstract class SearchHistory:
14641473 def defineBynameImplicit (tpe : Type , result : SearchSuccess )(using Context ): SearchResult =
14651474 root.defineBynameImplicit(tpe, result)
14661475
1476+ /** There is a qualifying call-by-name parameter in the history
1477+ * that cannot be used since is it not fully defined. Used for error reporting.
1478+ */
1479+ def disqualifiedType : Type =
1480+ def loop (h : SearchHistory ): Type = h match
1481+ case h : OpenSearch => if h.disqualified then h.pt else loop(h.outer)
1482+ case _ => NoType
1483+ loop(this )
1484+
14671485 // This is NOOP unless at the root of this search history.
14681486 def emitDictionary (span : Span , result : SearchResult )(using Context ): SearchResult = result
14691487
@@ -1483,6 +1501,10 @@ case class OpenSearch(cand: Candidate, pt: Type, outer: SearchHistory)(using Con
14831501 // An example is in neg/9504.scala
14841502 lazy val typeSize = pt.typeSize
14851503 lazy val coveringSet = pt.coveringSet
1504+
1505+ // Set if there would be a qualifying call-by-name parameter
1506+ // that cannot be used since is it not fully defined
1507+ var disqualified : Boolean = false
14861508end OpenSearch
14871509
14881510/**
0 commit comments