summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-10-19 17:19:08 +0000
committerPaul Phillips <paulp@improving.org>2011-10-19 17:19:08 +0000
commit8fc7a72a2b7765b6f5c6c5feb2bcaae58e735396 (patch)
tree26f3154d1ff9fb8d90f842f3c39fcf35b964a790
parentfb2353db6cc296289092ffa948e2e1c5f06c0d59 (diff)
downloadscala-8fc7a72a2b7765b6f5c6c5feb2bcaae58e735396.tar.gz
scala-8fc7a72a2b7765b6f5c6c5feb2bcaae58e735396.tar.bz2
scala-8fc7a72a2b7765b6f5c6c5feb2bcaae58e735396.zip
Cycle defense.
Notice when a typeref's info creates an obvious cycle, so we can see an error instead of a stack overflow. Closes SI-5093, review by moors.
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala8
-rw-r--r--test/files/neg/t2918.check5
-rw-r--r--test/files/neg/t5093.check10
-rw-r--r--test/files/neg/t5093.scala3
4 files changed, 24 insertions, 2 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index e85dc6de95..7b77c8addf 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -1772,7 +1772,13 @@ trait Types extends api.Types { self: SymbolTable =>
val symInfo = sym.info
if (thisInfoCache == null || (symInfo ne symInfoCache)) {
symInfoCache = symInfo
- thisInfoCache = transformInfo(symInfo)
+ thisInfoCache = transformInfo(symInfo) match {
+ // If a subtyping cycle is not detected here, we'll likely enter an infinite
+ // loop before a sensible error can be issued. SI-5093 is one example.
+ case x: SubType if x.supertype eq this =>
+ throw new TypeError("illegal cyclic reference involving " + sym)
+ case tp => tp
+ }
}
thisInfoCache
}
diff --git a/test/files/neg/t2918.check b/test/files/neg/t2918.check
index e67f24ec57..263beab518 100644
--- a/test/files/neg/t2918.check
+++ b/test/files/neg/t2918.check
@@ -1,7 +1,10 @@
+t2918.scala:2: error: illegal cyclic reference involving type A
+ def g[X, A[X] <: A[X]](x: A[X]) = x
+ ^
t2918.scala:2: error: cyclic aliasing or subtyping involving type A
def g[X, A[X] <: A[X]](x: A[X]) = x
^
t2918.scala:2: error: A does not take type parameters
def g[X, A[X] <: A[X]](x: A[X]) = x
^
-two errors found
+three errors found
diff --git a/test/files/neg/t5093.check b/test/files/neg/t5093.check
new file mode 100644
index 0000000000..daba460011
--- /dev/null
+++ b/test/files/neg/t5093.check
@@ -0,0 +1,10 @@
+t5093.scala:2: error: illegal cyclic reference involving type C
+ def f[C[X] <: C[X]](l: C[_]) = l.x
+ ^
+t5093.scala:2: error: cyclic aliasing or subtyping involving type C
+ def f[C[X] <: C[X]](l: C[_]) = l.x
+ ^
+t5093.scala:2: error: C does not take type parameters
+ def f[C[X] <: C[X]](l: C[_]) = l.x
+ ^
+three errors found
diff --git a/test/files/neg/t5093.scala b/test/files/neg/t5093.scala
new file mode 100644
index 0000000000..9cde364dee
--- /dev/null
+++ b/test/files/neg/t5093.scala
@@ -0,0 +1,3 @@
+class T {
+ def f[C[X] <: C[X]](l: C[_]) = l.x
+}