summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Implicits.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index a777f483e5..0538dfec7e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -839,11 +839,22 @@ trait Implicits {
if (divergentError.isEmpty) divergentError = Some(err)
}
+ def retainRemainingDivergentErrors() = {
+ val saved = divergentError.getOrElse(null)
+ context.reportBuffer.retainErrors {
+ case err: DivergentImplicitTypeError => err ne saved
+ }
+ }
+
def issueSavedDivergentError() {
divergentError foreach (err => context.issue(err))
}
def apply(search: SearchResult, i: ImplicitInfo, errors: Seq[AbsTypeError]): SearchResult = {
+ // A divergent error from a nested implicit search will be found in `errors`. Stash that
+ // aside to be re-issued if this implicit search fails.
+ errors.collectFirst { case err: DivergentImplicitTypeError => err } foreach saveDivergent
+
if (search.isDivergent && divergentError.isEmpty) {
// Divergence triggered by `i` at this level of the implicit serach. We haven't
// seen divergence so far, we won't issue this error just yet, and instead temporarily
@@ -879,16 +890,18 @@ trait Implicits {
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 =>
// We don't want errors that occur during checking implicit info
- // to influence the check of further infos.
- context.reportBuffer.retainErrors {
- case err: DivergentImplicitTypeError => true
- }
+ // to influence the check of further infos, but we should retain divergent implicit errors
+ // (except for the one we already squirreled away)
+ DivergentImplicitRecovery.retainRemainingDivergentErrors()
rankImplicits(is, acc)
case newBest =>
best = newBest