diff options
author | Hubert Plociniczak <hubert.plociniczak@gmail.com> | 2013-02-19 17:16:13 +0100 |
---|---|---|
committer | Hubert Plociniczak <hubert.plociniczak@gmail.com> | 2013-04-26 16:20:38 +0200 |
commit | accaa314f3473553d9ffaff8c37e3c5b29f0f2e3 (patch) | |
tree | b020cbdb01a335ce41aa597c8f3cef8551b0370e /src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | |
parent | f33af58f3b6538398da6974275099fb18560e92d (diff) | |
download | scala-accaa314f3473553d9ffaff8c37e3c5b29f0f2e3.tar.gz scala-accaa314f3473553d9ffaff8c37e3c5b29f0f2e3.tar.bz2 scala-accaa314f3473553d9ffaff8c37e3c5b29f0f2e3.zip |
SI-7291: No exception throwing for diverging implicit expansion
Since we don't throw exceptions for normal errors it was a bit odd
that we don't do that for DivergingImplicit.
As SI-7291 shows, the logic behind catching/throwing exception
was broken for divergence. Instead of patching it, I rewrote
the mechanism so that we now another SearchFailure type related
to diverging expansion, similar to ambiguous implicit scenario.
The logic to prevent diverging expansion from stopping the search
had to be slightly adapted but works as usual.
The upside is that we don't have to catch diverging implicit
for example in the presentation compiler which was again showing
that something was utterly broken with the exception approach.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 89fc55bc2c..5dd945eaea 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -59,6 +59,23 @@ trait ContextErrors { def errPos = tree.pos } + // Unlike other type errors diverging implicit expansion + // will be re-issued explicitly on failed implicit argument search. + // This is because we want to: + // 1) provide better error message than just "implicit not found" + // 2) provide the type of the implicit parameter for which we got diverging expansion + // (pt at the point of divergence gives less information to the user) + // Note: it is safe to delay error message generation in this case + // becasue we don't modify implicits' infos. + case class DivergentImplicitTypeError(tree: Tree, pt0: Type, sym: Symbol) extends AbsTypeError { + def errPos: Position = tree.pos + def errMsg: String = errMsgForPt(pt0) + def kind = ErrorKinds.Divergent + def withPt(pt: Type): AbsTypeError = NormalTypeError(tree, errMsgForPt(pt), kind) + private def errMsgForPt(pt: Type) = + s"diverging implicit expansion for type ${pt}\nstarting with ${sym.fullLocationString}" + } + case class AmbiguousTypeError(underlyingTree: Tree, errPos: Position, errMsg: String, kind: ErrorKind = ErrorKinds.Ambiguous) extends AbsTypeError case class PosAndMsgTypeError(errPos: Position, errMsg: String, kind: ErrorKind = ErrorKinds.Normal) extends AbsTypeError @@ -72,9 +89,6 @@ trait ContextErrors { issueTypeError(SymbolTypeError(sym, msg)) } - def issueDivergentImplicitsError(tree: Tree, msg: String)(implicit context: Context) { - issueTypeError(NormalTypeError(tree, msg, ErrorKinds.Divergent)) - } def issueAmbiguousTypeError(pre: Type, sym1: Symbol, sym2: Symbol, err: AmbiguousTypeError)(implicit context: Context) { context.issueAmbiguousError(pre, sym1, sym2, err) @@ -1182,9 +1196,7 @@ trait ContextErrors { } def DivergingImplicitExpansionError(tree: Tree, pt: Type, sym: Symbol)(implicit context0: Context) = - issueDivergentImplicitsError(tree, - "diverging implicit expansion for type "+pt+"\nstarting with "+ - sym.fullLocationString) + issueTypeError(DivergentImplicitTypeError(tree, pt, sym)) } object NamesDefaultsErrorsGen { |