Skip to content

Commit b8e20de

Browse files
committed
Refactor bestImplicit
No need to query recursiveRef twice
1 parent 2266d1d commit b8e20de

File tree

1 file changed

+34
-38
lines changed

1 file changed

+34
-38
lines changed

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

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -975,13 +975,10 @@ trait Implicits:
975975
if (argument.isEmpty) i"missing implicit parameter of type $pt after typer"
976976
else i"type error: ${argument.tpe} does not conform to $pt${err.whyNoMatchStr(argument.tpe, pt)}")
977977
val result0 =
978-
try
979-
new ImplicitSearch(pt, argument, span).bestImplicit(contextual = true)
980-
catch {
981-
case ce: CyclicReference =>
982-
ce.inImplicitSearch = true
983-
throw ce
984-
}
978+
try ImplicitSearch(pt, argument, span).bestImplicit
979+
catch case ce: CyclicReference =>
980+
ce.inImplicitSearch = true
981+
throw ce
985982

986983
val result =
987984
result0 match {
@@ -1121,7 +1118,7 @@ trait Implicits:
11211118
}
11221119

11231120
/** Search a list of eligible implicit references */
1124-
def searchImplicits(eligible: List[Candidate], contextual: Boolean): SearchResult = {
1121+
private def searchImplicit(eligible: List[Candidate], contextual: Boolean): SearchResult =
11251122

11261123
/** Compare previous success with reference and level to determine which one would be chosen, if
11271124
* an implicit starting with the reference was found.
@@ -1292,11 +1289,33 @@ trait Implicits:
12921289
}
12931290

12941291
rank(sort(eligible), NoMatchingImplicitsFailure, Nil)
1295-
}
1296-
// end searchImplicits
1292+
end searchImplicit
1293+
1294+
private def searchImplicit(contextual: Boolean): SearchResult =
1295+
val eligible =
1296+
if contextual then ctx.implicits.eligible(wildProto)
1297+
else implicitScope(wildProto).eligible
1298+
searchImplicit(eligible, contextual) match
1299+
case result: SearchSuccess =>
1300+
result
1301+
case failure: SearchFailure =>
1302+
failure.reason match
1303+
case _: AmbiguousImplicits => failure
1304+
case reason =>
1305+
if contextual then
1306+
searchImplicit(contextual = false).recoverWith {
1307+
failure2 => failure2.reason match
1308+
case _: AmbiguousImplicits => failure2
1309+
case _ =>
1310+
reason match
1311+
case (_: DivergingImplicit) => failure
1312+
case _ => List(failure, failure2).maxBy(_.tree.treeSize)
1313+
}
1314+
else failure
1315+
end searchImplicit
12971316

12981317
/** Find a unique best implicit reference */
1299-
def bestImplicit(contextual: Boolean): SearchResult =
1318+
def bestImplicit: SearchResult =
13001319
// Before searching for contextual or implicit scope candidates we first check if
13011320
// there is an under construction or already constructed term with which we can tie
13021321
// the knot.
@@ -1305,35 +1324,12 @@ trait Implicits:
13051324
// effectively in a more inner context than any other definition provided by
13061325
// explicit definitions. Consequently these terms have the highest priority and no
13071326
// other candidates need to be considered.
1308-
recursiveRef(pt) match {
1327+
recursiveRef match
13091328
case ref: TermRef =>
13101329
SearchSuccess(tpd.ref(ref).withSpan(span.startPos), ref, 0)(ctx.typerState, ctx.gadt)
13111330
case _ =>
1312-
val eligible =
1313-
if (contextual) ctx.implicits.eligible(wildProto)
1314-
else implicitScope(wildProto).eligible
1315-
searchImplicits(eligible, contextual) match {
1316-
case result: SearchSuccess =>
1317-
result
1318-
case failure: SearchFailure =>
1319-
failure.reason match {
1320-
case _: AmbiguousImplicits => failure
1321-
case reason =>
1322-
if (contextual)
1323-
bestImplicit(contextual = false).recoverWith {
1324-
failure2 => failure2.reason match {
1325-
case _: AmbiguousImplicits => failure2
1326-
case _ =>
1327-
reason match {
1328-
case (_: DivergingImplicit) => failure
1329-
case _ => List(failure, failure2).maxBy(_.tree.treeSize)
1330-
}
1331-
}
1332-
}
1333-
else failure
1334-
}
1335-
}
1336-
}
1331+
searchImplicit(contextual = true)
1332+
end bestImplicit
13371333

13381334
def implicitScope(tp: Type): OfTypeImplicits = ctx.run.implicitScope(tp)
13391335

@@ -1413,7 +1409,7 @@ trait Implicits:
14131409
* @param pt The target type being searched for.
14141410
* @result The corresponding dictionary reference if any, NoType otherwise.
14151411
*/
1416-
def recursiveRef(pt: Type)(using Context): Type =
1412+
def recursiveRef(using Context): Type =
14171413
val widePt = pt.widenExpr
14181414

14191415
ctx.searchHistory.refBynameImplicit(widePt).orElse {

0 commit comments

Comments
 (0)