diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-10-07 17:35:47 +0200 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-10-09 09:49:53 +0200 |
commit | 4902c84cb049764dddc263976affa80bd6d44997 (patch) | |
tree | a62dcb9184afd81d20aa80251cdddd372157bc07 | |
parent | c038732f1b302dd128b32512aab4cf0826752599 (diff) | |
download | scala-4902c84cb049764dddc263976affa80bd6d44997.tar.gz scala-4902c84cb049764dddc263976affa80bd6d44997.tar.bz2 scala-4902c84cb049764dddc263976affa80bd6d44997.zip |
SI-8890 handle reference to overload with error
When buffering, we must report the ambiguity error to avoid a stack overflow.
When the error refers to erroneous types/symbols,
we don't report it directly to the user,
because there will be an underlying error that's the root cause.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 41 | ||||
-rw-r--r-- | test/files/neg/t8890.check | 4 | ||||
-rw-r--r-- | test/files/neg/t8890.scala | 11 |
3 files changed, 40 insertions, 16 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 20e462bbce..866ca37303 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -885,22 +885,31 @@ trait ContextErrors { val WrongNumber, NoParams, ArgsDoNotConform = Value } - private def issueAmbiguousTypeErrorUnlessErroneous(pos: Position, pre: Type, sym1: Symbol, sym2: Symbol, rest: String): Unit = - if (!(pre.isErroneous || sym1.isErroneous || sym2.isErroneous)) { - if (sym1.hasDefault && sym2.hasDefault && sym1.enclClass == sym2.enclClass) { - val methodName = nme.defaultGetterToMethod(sym1.name) - context.issueAmbiguousError(AmbiguousTypeError(sym1.enclClass.pos, - "in "+ sym1.enclClass +", multiple overloaded alternatives of " + methodName + - " define default arguments")) - } else { - context.issueAmbiguousError(AmbiguousTypeError(pos, - ("ambiguous reference to overloaded definition,\n" + - "both " + sym1 + sym1.locationString + " of type " + pre.memberType(sym1) + - "\nand " + sym2 + sym2.locationString + " of type " + pre.memberType(sym2) + - "\nmatch " + rest) - )) - } - } + private def issueAmbiguousTypeErrorUnlessErroneous(pos: Position, pre: Type, sym1: Symbol, sym2: Symbol, rest: String): Unit = { + // To avoid stack overflows (SI-8890), we MUST (at least) report when either `validTargets` OR `ambiguousSuppressed` + // More details: + // If `!context.ambiguousErrors`, `reporter.issueAmbiguousError` (which `context.issueAmbiguousError` forwards to) + // buffers ambiguous errors. In this case, to avoid looping, we must issue even if `!validTargets`. (TODO: why?) + // When not buffering (and thus reporting to the user), we shouldn't issue unless `validTargets`, + // otherwise we report two different errors that trace back to the same root cause, + // and unless `validTargets`, we don't know for sure the ambiguity is real anyway. + val validTargets = !(pre.isErroneous || sym1.isErroneous || sym2.isErroneous) + val ambiguousBuffered = !context.ambiguousErrors + if (validTargets || ambiguousBuffered) + context.issueAmbiguousError( + if (sym1.hasDefault && sym2.hasDefault && sym1.enclClass == sym2.enclClass) { + val methodName = nme.defaultGetterToMethod(sym1.name) + AmbiguousTypeError(sym1.enclClass.pos, + s"in ${sym1.enclClass}, multiple overloaded alternatives of $methodName define default arguments") + + } else { + AmbiguousTypeError(pos, + "ambiguous reference to overloaded definition,\n" + + s"both ${sym1.fullLocationString} of type ${pre.memberType(sym1)}\n" + + s"and ${sym2.fullLocationString} of type ${pre.memberType(sym2)}\n" + + s"match $rest") + }) + } def AccessError(tree: Tree, sym: Symbol, ctx: Context, explanation: String): AbsTypeError = AccessError(tree, sym, ctx.enclClass.owner.thisType, ctx.enclClass.owner, explanation) diff --git a/test/files/neg/t8890.check b/test/files/neg/t8890.check new file mode 100644 index 0000000000..1b69d6cf30 --- /dev/null +++ b/test/files/neg/t8890.check @@ -0,0 +1,4 @@ +t8890.scala:6: error: not found: type Str + def bar(x: Str): Unit = ??? + ^ +one error found diff --git a/test/files/neg/t8890.scala b/test/files/neg/t8890.scala new file mode 100644 index 0000000000..cbdeb11d43 --- /dev/null +++ b/test/files/neg/t8890.scala @@ -0,0 +1,11 @@ +package foo + +class A { + /** The other */ + def bar(x: Int): Unit = ??? + def bar(x: Str): Unit = ??? +} + +class B { + (new A).bar(0) +}
\ No newline at end of file |