@@ -1369,17 +1369,15 @@ trait Implicits:
13691369 @ tailrec
13701370 def loop (history : SearchHistory , belowByname : Boolean ): Boolean =
13711371 history match
1372- case OpenSearch (cand1, tp, outer) =>
1372+ case prev @ OpenSearch (cand1, tp, outer) =>
13731373 if cand1.ref eq cand.ref then
1374- val wideTp = tp.widenExpr
1375- lazy val wildTp = wildApprox(wideTp)
1376- lazy val tpSize = wideTp.typeSize
1374+ lazy val wildTp = wildApprox(tp.widenExpr)
13771375 if belowByname && (wildTp <:< wildPt) then
13781376 false
1379- else if tpSize > ptSize || wideTp .coveringSet != ptCoveringSet then
1377+ else if prev.typeSize > ptSize || prev .coveringSet != ptCoveringSet then
13801378 loop(outer, tp.isByName || belowByname)
13811379 else
1382- tpSize < ptSize
1380+ prev.typeSize < ptSize
13831381 || wildTp =:= wildPt
13841382 || loop(outer, tp.isByName || belowByname)
13851383 else loop(outer, tp.isByName || belowByname)
@@ -1434,7 +1432,7 @@ end Implicits
14341432/**
14351433 * Records the history of currently open implicit searches.
14361434 *
1437- * A search history maintains a list of open implicit searches (`open `) a shortcut flag
1435+ * A search history maintains a list of open implicit searches (`openSearchPairs `) a shortcut flag
14381436 * indicating whether any of these are by name (`byname`) and a reference to the root
14391437 * search history (`root`) which in turn maintains a possibly empty dictionary of
14401438 * recursive implicit terms constructed during this search.
@@ -1448,7 +1446,7 @@ abstract class SearchHistory:
14481446 val root : SearchRoot
14491447 /** Does this search history contain any by name implicit arguments. */
14501448 val byname : Boolean
1451- def open : List [(Candidate , Type )]
1449+ def openSearchPairs : List [(Candidate , Type )]
14521450
14531451 /**
14541452 * Create the state for a nested implicit search.
@@ -1469,13 +1467,22 @@ abstract class SearchHistory:
14691467 // This is NOOP unless at the root of this search history.
14701468 def emitDictionary (span : Span , result : SearchResult )(using Context ): SearchResult = result
14711469
1472- override def toString : String = s " SearchHistory(open = $open , byname = $byname) "
1470+ override def toString : String = s " SearchHistory(open = $openSearchPairs , byname = $byname) "
14731471end SearchHistory
14741472
1475- case class OpenSearch (cand : Candidate , pt : Type , outer : SearchHistory ) extends SearchHistory :
1473+ case class OpenSearch (cand : Candidate , pt : Type , outer : SearchHistory )( using Context ) extends SearchHistory :
14761474 val root = outer.root
14771475 val byname = outer.byname || pt.isByName
1478- def open = (cand, pt) :: outer.open
1476+ def openSearchPairs = (cand, pt) :: outer.openSearchPairs
1477+
1478+ // The typeSize and coveringSet of the current search.
1479+ // Note: It is important to cache size and covering sets since types
1480+ // in search histories can contain type variables that can be instantiated
1481+ // by nested implicit searches, thus leading to types in search histories
1482+ // that grow larger the deeper the search gets. This can mask divergence.
1483+ // An example is in neg/9504.scala
1484+ lazy val typeSize = pt.typeSize
1485+ lazy val coveringSet = pt.coveringSet
14791486end OpenSearch
14801487
14811488/**
@@ -1484,7 +1491,7 @@ end OpenSearch
14841491final class SearchRoot extends SearchHistory :
14851492 val root = this
14861493 val byname = false
1487- def open = Nil
1494+ def openSearchPairs = Nil
14881495
14891496 /** The dictionary of recursive implicit types and corresponding terms for this search. */
14901497 var myImplicitDictionary : mutable.Map [Type , (TermRef , tpd.Tree )] = null
0 commit comments