@@ -1362,24 +1362,19 @@ trait Implicits { self: Typer =>
1362
1362
* recursive references and emit a complete implicit dictionary when the outermost search
1363
1363
* is complete.
1364
1364
*/
1365
- abstract class SearchHistory { outer =>
1365
+ abstract class SearchHistory :
1366
1366
val root : SearchRoot
1367
- val open : List [(Candidate , Type )]
1368
1367
/** Does this search history contain any by name implicit arguments. */
1369
1368
val byname : Boolean
1369
+ def open : List [(Candidate , Type )]
1370
1370
1371
1371
/**
1372
1372
* Create the state for a nested implicit search.
1373
1373
* @param cand The candidate implicit to be explored.
1374
1374
* @param pt The target type for the above candidate.
1375
1375
* @result The nested history.
1376
1376
*/
1377
- def nest (cand : Candidate , pt : Type )(using Context ): SearchHistory =
1378
- new SearchHistory {
1379
- val root = outer.root
1380
- val open = (cand, pt) :: outer.open
1381
- val byname = outer.byname || isByname(pt)
1382
- }
1377
+ def nest (cand : Candidate , pt : Type )(using Context ): OpenSearch = OpenSearch (cand, pt, this )
1383
1378
1384
1379
def isByname (tp : Type ): Boolean = tp.isInstanceOf [ExprType ]
1385
1380
@@ -1410,22 +1405,25 @@ abstract class SearchHistory { outer =>
1410
1405
// as we ascend the chain of open implicits to the outermost search context.
1411
1406
1412
1407
@ tailrec
1413
- def loop (ois : List [( Candidate , Type )] , belowByname : Boolean ): Boolean =
1414
- ois match {
1415
- case Nil => false
1416
- case (hd @ ( cand1, tp)) :: tl =>
1417
- if ( cand1.ref == cand.ref) {
1408
+ def loop (history : SearchHistory , belowByname : Boolean ): Boolean =
1409
+ history match
1410
+ case _ : SearchRoot => false
1411
+ case OpenSearch ( cand1, tp, outer) =>
1412
+ if cand1.ref == cand.ref then
1418
1413
val wideTp = tp.widenExpr
1419
1414
lazy val wildTp = wildApprox(wideTp)
1420
1415
lazy val tpSize = wideTp.typeSize
1421
- if (belowByname && (wildTp <:< wildPt)) false
1422
- else if (tpSize > ptSize || wideTp.coveringSet != ptCoveringSet) loop(tl, isByname(tp) || belowByname)
1423
- else tpSize < ptSize || wildTp =:= wildPt || loop(tl, isByname(tp) || belowByname)
1424
- }
1425
- else loop(tl, isByname(tp) || belowByname)
1426
- }
1416
+ if belowByname && (wildTp <:< wildPt) then
1417
+ false
1418
+ else if tpSize > ptSize || wideTp.coveringSet != ptCoveringSet then
1419
+ loop(outer, isByname(tp) || belowByname)
1420
+ else
1421
+ tpSize < ptSize
1422
+ || wildTp =:= wildPt
1423
+ || loop(outer, isByname(tp) || belowByname)
1424
+ else loop(outer, isByname(tp) || belowByname)
1427
1425
1428
- loop(open , isByname(pt))
1426
+ loop(this , isByname(pt))
1429
1427
}
1430
1428
1431
1429
/**
@@ -1457,17 +1455,16 @@ abstract class SearchHistory { outer =>
1457
1455
// argument as we ascend the chain of open implicits to the outermost search
1458
1456
// context.
1459
1457
@ tailrec
1460
- def loop (ois : List [(Candidate , Type )], belowByname : Boolean ): Type =
1461
- ois match {
1462
- case (hd@ (cand, tp)) :: tl if (belowByname || isByname(tp)) && tp.widenExpr <:< widePt => tp
1463
- case (_, tp) :: tl => loop(tl, belowByname || isByname(tp))
1458
+ def loop (history : SearchHistory , belowByname : Boolean ): Type =
1459
+ history match
1460
+ case OpenSearch (cand, tp, outer) =>
1461
+ if (belowByname || isByname(tp)) && tp.widenExpr <:< widePt then tp
1462
+ else loop(outer, belowByname || isByname(tp))
1464
1463
case _ => NoType
1465
- }
1466
1464
1467
- loop(open , bynamePt) match {
1465
+ loop(this , bynamePt) match
1468
1466
case NoType => NoType
1469
1467
case tp => ctx.searchHistory.linkBynameImplicit(tp.widenExpr)
1470
- }
1471
1468
}
1472
1469
}
1473
1470
}
@@ -1484,15 +1481,21 @@ abstract class SearchHistory { outer =>
1484
1481
def emitDictionary (span : Span , result : SearchResult )(using Context ): SearchResult = result
1485
1482
1486
1483
override def toString : String = s " SearchHistory(open = $open, byname = $byname) "
1487
- }
1484
+ end SearchHistory
1485
+
1486
+ case class OpenSearch (cand : Candidate , pt : Type , outer : SearchHistory ) extends SearchHistory :
1487
+ val root = outer.root
1488
+ val byname = outer.byname || isByname(pt)
1489
+ def open = (cand, pt) :: outer.open
1490
+ end OpenSearch
1488
1491
1489
1492
/**
1490
1493
* The the state corresponding to the outermost context of an implicit searcch.
1491
1494
*/
1492
- final class SearchRoot extends SearchHistory {
1495
+ final class SearchRoot extends SearchHistory :
1493
1496
val root = this
1494
- val open = Nil
1495
1497
val byname = false
1498
+ def open = Nil
1496
1499
1497
1500
/** The dictionary of recursive implicit types and corresponding terms for this search. */
1498
1501
var implicitDictionary0 : mutable.Map [Type , (TermRef , tpd.Tree )] = null
@@ -1653,7 +1656,7 @@ final class SearchRoot extends SearchHistory {
1653
1656
success.copy(tree = blk)(success.tstate, success.gstate)
1654
1657
}
1655
1658
}
1656
- }
1659
+ end SearchRoot
1657
1660
1658
1661
/** A set of term references where equality is =:= */
1659
1662
sealed class TermRefSet (using Context ):
0 commit comments