diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 16 |
2 files changed, 19 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 6ee09d064f..6b67ee886e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -713,10 +713,17 @@ trait ContextErrors { "constructor cannot be instantiated to expected type" + foundReqMsg(restpe, pt)) setError(tree) } - - def NoBestMethodAlternativeError(tree: Tree, argtpes: List[Type], pt: Type) = + + def NoBestMethodAlternativeError(tree: Tree, argtpes: List[Type], pt: Type) = { 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). + // This avoids entering infinite loop in doTypeApply. + // TODO: maybe we should do the same thing with inferExprAlternative. + if (implicitly[Context].reportErrors) setError(tree) + } def AmbiguousMethodAlternativeError(tree: Tree, pre: Type, best: Symbol, firstCompeting: Symbol, argtpes: List[Type], pt: Type) = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index b97fbebec2..e1aa8b46eb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1388,7 +1388,7 @@ trait Infer { NoBestExprAlternativeError(tree, pt) } else if (!competing.isEmpty) { if (secondTry) NoBestExprAlternativeError(tree, pt) - else { if (!pt.isErroneous) AmbiguousExprAlternativeError(tree, pre, best, competing.head, pt) } + else if (!pt.isErroneous) AmbiguousExprAlternativeError(tree, pre, best, competing.head, pt) } else { // val applicable = alts1 filter (alt => // global.typer.infer.isWeaklyCompatible(pre.memberType(alt), pt)) @@ -1398,10 +1398,14 @@ trait Infer { } } - @inline private def inSilentMode(expr: Typer => Boolean): Boolean = { - val silentContext = context.makeSilent(context.ambiguousErrors) - val res = expr(newTyper(silentContext)) - if (silentContext.hasErrors) false else res + @inline private def inSilentMode(context: Context)(expr: => Boolean): Boolean = { + val oldState = context.state + context.setBufferErrors() + val res = expr + val contextWithErrors = context.hasErrors + context.flushBuffer() + context.restoreState(oldState) + res && !contextWithErrors } // Checks against the name of the parameter and also any @deprecatedName. @@ -1472,7 +1476,7 @@ trait Infer { val applicable = resolveOverloadedMethod(argtpes, { alts filter { alt => - inSilentMode(typer0 => typer0.infer.isApplicable(undetparams, followApply(pre.memberType(alt)), argtpes, pt)) && + inSilentMode(context)(isApplicable(undetparams, followApply(pre.memberType(alt)), argtpes, pt)) && (!varArgsOnly || isVarArgsList(alt.tpe.params)) } }) |