Skip to content

Commit

Permalink
SI-6912 Avoid a typer cycle in overload resolution.
Browse files Browse the repository at this point in the history
c800d1f, and followup commits 1ddc935 and b10b582
modified error handling in `Infer#inferExprAlternative`.
After these changes, this method could fail to resolve
the overloaded alternative if:

     best != NoSymbol
  && !competing.isEmpty
  && !noAlternatives
  && pt.isErroneous

This commit calls `setError` in that case, which
prevents the cycle in `adapt`.

While I didn't extract a reproduction from the
original code base, I've included a test case that
exhibits the same symptom.

It was actually pretty tough to find an program that
got close to this code path, but luckilly we've been
pretty close to this bug in SI-5553 / 4f99c2e, and those
test cases formed the basis for this one.
  • Loading branch information
retronym committed Jan 8, 2013
1 parent 1381cda commit 7a23562
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/compiler/scala/tools/nsc/typechecker/Infer.scala
Expand Up @@ -1510,6 +1510,13 @@ trait Infer extends Checkable {
} else if (!competing.isEmpty) {
if (noAlternatives) NoBestExprAlternativeError(tree, pt, isSecondTry)
else if (!pt.isErroneous) AmbiguousExprAlternativeError(tree, pre, best, competing.head, pt, isSecondTry)
else {
// SI-6912 Don't give up and leave an OverloadedType on the tree.
// Originally I wrote this as `if (secondTry) ... `, but `tryTwice` won't attempt the second try
// unless an error is issued. We're not issuing an error, in the assumption that it would be
// spurious in light of the erroneous expected type
setError(tree)
}
} else {
// val applicable = alts1 filter (alt =>
// global.typer.infer.isWeaklyCompatible(pre.memberType(alt), pt))
Expand Down
4 changes: 4 additions & 0 deletions test/files/neg/t6912.check
@@ -0,0 +1,4 @@
t6912.scala:8: error: not found: type Xxxx
def test[T]: Xxxx = Foo1[T]
^
one error found
9 changes: 9 additions & 0 deletions test/files/neg/t6912.scala
@@ -0,0 +1,9 @@
object Foo1 {
def apply[T](a: Int = 0): Nothing = sys.error("")
def apply[T](z: String = ""): Nothing = sys.error("")
}

object Test {
// Triggered a cycle in Typers#adapt
def test[T]: Xxxx = Foo1[T]
}

0 comments on commit 7a23562

Please sign in to comment.