summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-01-04 07:05:19 +0100
committerPaul Phillips <paulp@improving.org>2012-01-04 06:24:23 -0800
commit6975b4888da9b56e2c06d45da8f483f2e33a102b (patch)
treeb4fa395843b6c573f584481848f37ee1c0ba5c68 /src
parentd188f6fdded6fdd9df3960d6085b9b80046c05ca (diff)
downloadscala-6975b4888da9b56e2c06d45da8f483f2e33a102b.tar.gz
scala-6975b4888da9b56e2c06d45da8f483f2e33a102b.tar.bz2
scala-6975b4888da9b56e2c06d45da8f483f2e33a102b.zip
Closes SI-5354.
The reason why the test case compiled without error is pretty devious: When checking the `Foo.x' implicit, a CyclicReference error occurs which causes the alternative to be discarded. Why a CylicReference? Because the inferencer tries to decide whether the owner of `z` is a subclass of the owner od `x`. To do this, it computed the info of the owner of `z1`, which is not complete because no result type for `f1` was given. Hence a CyclicReference error. The fix is twofold: (1) We make isNonBottomSubClass smarter so that it always returns false if the symbol in question is not a type; hence the info need not be computed. (2) It's dubious to swallow CyclicReference errors anywhere, but I deemed it too risky to propagate them. But at least the CyclicReference is now logged if -Ylog-implicit is true. This hopefully spares future maintainers the same detective work I had to go through when digging this out.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala9
2 files changed, 17 insertions, 7 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 0c57f0c43a..e629b0ed43 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -1244,12 +1244,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
final def isNestedIn(that: Symbol): Boolean =
owner == that || owner != NoSymbol && (owner isNestedIn that)
-
- /** Is this class symbol a subclass of that symbol? */
- final def isNonBottomSubClass(that: Symbol): Boolean = (
- (this eq that) || this.isError || that.isError ||
- info.baseTypeIndex(that) >= 0
- )
+
+ /** Is this class symbol a subclass of that symbol,
+ * and is this class symbol also different from Null or Nothing? */
+ def isNonBottomSubClass(that: Symbol): Boolean = false
/** Overridden in NullClass and NothingClass for custom behavior.
*/
@@ -2226,6 +2224,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
super.info_=(tp)
}
+ final override def isNonBottomSubClass(that: Symbol): Boolean = (
+ (this eq that) || this.isError || that.isError ||
+ info.baseTypeIndex(that) >= 0
+ )
+
override def reset(completer: Type) {
super.reset(completer)
tpePeriod = NoPeriod
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index d54cb248cf..77dde88a80 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -816,7 +816,14 @@ trait Implicits {
val newPending = undoLog undo {
is filterNot (alt => alt == i || {
try improves(i, alt)
- catch { case e: CyclicReference => true }
+ catch {
+ case e: CyclicReference =>
+ if (printInfers) {
+ println(i+" discarded because cyclic reference occurred")
+ e.printStackTrace()
+ }
+ true
+ }
})
}
rankImplicits(newPending, i :: acc)