diff options
author | Hubert Plociniczak <hubert.plociniczak@gmail.com> | 2012-05-22 00:20:11 +0200 |
---|---|---|
committer | Hubert Plociniczak <hubert.plociniczak@gmail.com> | 2012-05-22 11:04:57 +0200 |
commit | 1ddc9358f551f4586adb1a540e0255fd0e5a33c9 (patch) | |
tree | 9e773c703d1512f49c6703a1f0172927367cd5cb /src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | |
parent | bbfbd6694d564552a6a8d903dc5d6e34f5976c2b (diff) | |
download | scala-1ddc9358f551f4586adb1a540e0255fd0e5a33c9.tar.gz scala-1ddc9358f551f4586adb1a540e0255fd0e5a33c9.tar.bz2 scala-1ddc9358f551f4586adb1a540e0255fd0e5a33c9.zip |
More consistent solution for errorenous situations when infering the alternative.
From now on we specify explicity which attempt is tried and setError on the tree
depending on that. Relying on the context was a nice idea to avoid that but was
fragile when we were in the silent mode (like checking named arguments).
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 7fa421e353..9aa1b1b9c2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -690,35 +690,43 @@ trait ContextErrors { setError(tree) } - def NoBestMethodAlternativeError(tree: Tree, argtpes: List[Type], pt: Type) = { + // side-effect on the tree, break the overloaded type cycle in infer + private def setErrorOnLastTry(lastTry: Boolean, tree: Tree) = if (lastTry) setError(tree) + + def NoBestMethodAlternativeError(tree: Tree, argtpes: List[Type], pt: Type, lastTry: Boolean) = { issueNormalTypeError(tree, applyErrorMsg(tree, " cannot be applied to ", argtpes, pt)) // since inferMethodAlternative modifies the state of the tree // we have to set the type of tree to ErrorType only in the very last - // fallback action that is done in the inference (tracking it manually is error prone). + // fallback action that is done in the inference. // This avoids entering infinite loop in doTypeApply. - if (implicitly[Context].reportErrors) setError(tree) + setErrorOnLastTry(lastTry, tree) + //if (implicitly[Context].reportErrors) setError(tree) } def AmbiguousMethodAlternativeError(tree: Tree, pre: Type, best: Symbol, - firstCompeting: Symbol, argtpes: List[Type], pt: Type) = { - val msg0 = - "argument types " + argtpes.mkString("(", ",", ")") + - (if (pt == WildcardType) "" else " and expected result type " + pt) - val (pos, msg) = ambiguousErrorMsgPos(tree.pos, pre, best, firstCompeting, msg0) - // discover last attempt in a similar way as for NoBestMethodAlternativeError - if (implicitly[Context].ambiguousErrors) setError(tree) - issueAmbiguousTypeError(pre, best, firstCompeting, AmbiguousTypeError(tree, pos, msg)) + firstCompeting: Symbol, argtpes: List[Type], pt: Type, lastTry: Boolean) = { + + if (!(argtpes exists (_.isErroneous)) && !pt.isErroneous) { + val msg0 = + "argument types " + argtpes.mkString("(", ",", ")") + + (if (pt == WildcardType) "" else " and expected result type " + pt) + val (pos, msg) = ambiguousErrorMsgPos(tree.pos, pre, best, firstCompeting, msg0) + setErrorOnLastTry(lastTry, tree) + issueAmbiguousTypeError(pre, best, firstCompeting, AmbiguousTypeError(tree, pos, msg)) + } else setError(tree) // do not even try further attempts because they should all fail + // even if this is not the last attempt (because of the SO's possibility on the horizon) + } - def NoBestExprAlternativeError(tree: Tree, pt: Type) = { + def NoBestExprAlternativeError(tree: Tree, pt: Type, lastTry: Boolean) = { issueNormalTypeError(tree, withAddendum(tree.pos)(typeErrorMsg(tree.symbol.tpe, pt, isPossiblyMissingArgs(tree.symbol.tpe, pt)))) - if (implicitly[Context].reportErrors) setError(tree) + setErrorOnLastTry(lastTry, tree) } - def AmbiguousExprAlternativeError(tree: Tree, pre: Type, best: Symbol, firstCompeting: Symbol, pt: Type) = { + def AmbiguousExprAlternativeError(tree: Tree, pre: Type, best: Symbol, firstCompeting: Symbol, pt: Type, lastTry: Boolean) = { val (pos, msg) = ambiguousErrorMsgPos(tree.pos, pre, best, firstCompeting, "expected type " + pt) - if (implicitly[Context].ambiguousErrors) setError(tree) + setErrorOnLastTry(lastTry, tree) issueAmbiguousTypeError(pre, best, firstCompeting, AmbiguousTypeError(tree, pos, msg)) } |