summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2014-04-01 10:25:48 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2014-04-01 10:34:11 -0700
commitafccae640cbfdd876e0eb3369570954d82adf508 (patch)
tree36828a615378b90ca86f00cc30c7f4b77991d0a2 /src/compiler/scala/tools/nsc/typechecker/Implicits.scala
parentd345424ecc32d7e077ebc2172e0c0cc4e338ed10 (diff)
downloadscala-afccae640cbfdd876e0eb3369570954d82adf508.tar.gz
scala-afccae640cbfdd876e0eb3369570954d82adf508.tar.bz2
scala-afccae640cbfdd876e0eb3369570954d82adf508.zip
Refactor rankImplicits, add some more docs
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Implicits.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala50
1 files changed, 26 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 976581f8f4..d87090fa46 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -891,31 +891,33 @@ trait Implicits {
* - if it matches, forget about all others it improves upon
*/
@tailrec private def rankImplicits(pending: Infos, acc: Infos): Infos = pending match {
- case Nil => acc
- case i :: is =>
- val typedImplicitResult = typedImplicit(i, ptChecked = true, isLocalToCallsite)
- // Pass the errors to `DivergentImplicitRecovery` so that it can note the first `DivergentImplicitTypeError`
- // that is being propagated from a nested implicit search;
- // this one will be re-issued if this level of the search fails.
- val recoveredResult = DivergentImplicitRecovery(typedImplicitResult, i, context.errors)
- recoveredResult match {
- case sr if sr.isDivergent =>
- Nil
- case sr if sr.isFailure =>
- rankImplicits(is, acc)
- case newBest =>
- best = newBest
- val newPending = undoLog undo {
- is filterNot (alt => alt == i || {
- try improves(i, alt)
- catch {
- case e: CyclicReference =>
- debugwarn(s"Discarding $i during implicit search due to cyclic reference")
- true
- }
- })
+ case Nil => acc
+ case firstPending :: otherPending =>
+ def firstPendingImproves(alt: ImplicitInfo) =
+ firstPending == alt || (
+ try improves(firstPending, alt)
+ catch {
+ case e: CyclicReference =>
+ debugwarn(s"Discarding $firstPending during implicit search due to cyclic reference.")
+ true
+ }
+ )
+
+ val typedFirstPending = typedImplicit(firstPending, ptChecked = true, isLocalToCallsite)
+
+ // Pass the errors to `DivergentImplicitRecovery` so that it can note
+ // the first `DivergentImplicitTypeError` that is being propagated
+ // from a nested implicit search; this one will be
+ // re-issued if this level of the search fails.
+ DivergentImplicitRecovery(typedFirstPending, firstPending, context.errors) match {
+ case sr if sr.isDivergent => Nil
+ case sr if sr.isFailure => rankImplicits(otherPending, acc)
+ case newBest =>
+ best = newBest // firstPending is our new best, since we already pruned last time around:
+ val pendingImprovingBest = undoLog undo {
+ otherPending filterNot firstPendingImproves
}
- rankImplicits(newPending, i :: acc)
+ rankImplicits(pendingImprovingBest, firstPending :: acc)
}
}