@@ -1369,17 +1369,15 @@ trait Implicits:
1369
1369
@ tailrec
1370
1370
def loop (history : SearchHistory , belowByname : Boolean ): Boolean =
1371
1371
history match
1372
- case OpenSearch (cand1, tp, outer) =>
1372
+ case prev @ OpenSearch (cand1, tp, outer) =>
1373
1373
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)
1377
1375
if belowByname && (wildTp <:< wildPt) then
1378
1376
false
1379
- else if tpSize > ptSize || wideTp .coveringSet != ptCoveringSet then
1377
+ else if prev.typeSize > ptSize || prev .coveringSet != ptCoveringSet then
1380
1378
loop(outer, tp.isByName || belowByname)
1381
1379
else
1382
- tpSize < ptSize
1380
+ prev.typeSize < ptSize
1383
1381
|| wildTp =:= wildPt
1384
1382
|| loop(outer, tp.isByName || belowByname)
1385
1383
else loop(outer, tp.isByName || belowByname)
@@ -1434,7 +1432,7 @@ end Implicits
1434
1432
/**
1435
1433
* Records the history of currently open implicit searches.
1436
1434
*
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
1438
1436
* indicating whether any of these are by name (`byname`) and a reference to the root
1439
1437
* search history (`root`) which in turn maintains a possibly empty dictionary of
1440
1438
* recursive implicit terms constructed during this search.
@@ -1448,7 +1446,7 @@ abstract class SearchHistory:
1448
1446
val root : SearchRoot
1449
1447
/** Does this search history contain any by name implicit arguments. */
1450
1448
val byname : Boolean
1451
- def open : List [(Candidate , Type )]
1449
+ def openSearchPairs : List [(Candidate , Type )]
1452
1450
1453
1451
/**
1454
1452
* Create the state for a nested implicit search.
@@ -1469,13 +1467,22 @@ abstract class SearchHistory:
1469
1467
// This is NOOP unless at the root of this search history.
1470
1468
def emitDictionary (span : Span , result : SearchResult )(using Context ): SearchResult = result
1471
1469
1472
- override def toString : String = s " SearchHistory(open = $open , byname = $byname) "
1470
+ override def toString : String = s " SearchHistory(open = $openSearchPairs , byname = $byname) "
1473
1471
end SearchHistory
1474
1472
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 :
1476
1474
val root = outer.root
1477
1475
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
1479
1486
end OpenSearch
1480
1487
1481
1488
/**
@@ -1484,7 +1491,7 @@ end OpenSearch
1484
1491
final class SearchRoot extends SearchHistory :
1485
1492
val root = this
1486
1493
val byname = false
1487
- def open = Nil
1494
+ def openSearchPairs = Nil
1488
1495
1489
1496
/** The dictionary of recursive implicit types and corresponding terms for this search. */
1490
1497
var myImplicitDictionary : mutable.Map [Type , (TermRef , tpd.Tree )] = null
0 commit comments