diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Implicits.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 21 |
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 |