diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-04-01 10:25:48 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-04-01 10:34:11 -0700 |
commit | afccae640cbfdd876e0eb3369570954d82adf508 (patch) | |
tree | 36828a615378b90ca86f00cc30c7f4b77991d0a2 | |
parent | d345424ecc32d7e077ebc2172e0c0cc4e338ed10 (diff) | |
download | scala-afccae640cbfdd876e0eb3369570954d82adf508.tar.gz scala-afccae640cbfdd876e0eb3369570954d82adf508.tar.bz2 scala-afccae640cbfdd876e0eb3369570954d82adf508.zip |
Refactor rankImplicits, add some more docs
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 50 |
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) } } |