From 8fc7a72a2b7765b6f5c6c5feb2bcaae58e735396 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 19 Oct 2011 17:19:08 +0000 Subject: 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. --- src/compiler/scala/reflect/internal/Types.scala | 8 +++++++- test/files/neg/t2918.check | 5 ++++- test/files/neg/t5093.check | 10 ++++++++++ test/files/neg/t5093.scala | 3 +++ 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 test/files/neg/t5093.check create mode 100644 test/files/neg/t5093.scala 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 +} -- cgit v1.2.3