summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-03-02 02:55:44 +0000
committerPaul Phillips <paulp@improving.org>2011-03-02 02:55:44 +0000
commite465571a4e1dcdd76d888da1e93108e0ee71ce85 (patch)
tree68080d88adc17b8c8b7962719e0d851bfa60a2e6
parente42733e9fe1f3af591976fbb48b66035253d85b9 (diff)
downloadscala-e465571a4e1dcdd76d888da1e93108e0ee71ce85.tar.gz
scala-e465571a4e1dcdd76d888da1e93108e0ee71ce85.tar.bz2
scala-e465571a4e1dcdd76d888da1e93108e0ee71ce85.zip
Added cycle detection to getParts.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala4
-rw-r--r--test/files/neg/bug4221.check6
-rw-r--r--test/files/neg/bug4221.scala10
3 files changed, 20 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 6d36c77b28..655e5dfe09 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -724,11 +724,15 @@ trait Implicits {
*/
private def companionImplicits(tp: Type): Infoss = {
val partMap = new LinkedHashMap[Symbol, Type]
+ val seen = mutable.HashSet[Type]() // cycle detection
/** Enter all parts of `tp` into `parts` set.
* This method is performance critical: about 2-4% of all type checking is spent here
*/
def getParts(tp: Type) {
+ if (seen(tp))
+ return
+ seen += tp
tp match {
case TypeRef(pre, sym, args) =>
if (sym.isClass) {
diff --git a/test/files/neg/bug4221.check b/test/files/neg/bug4221.check
new file mode 100644
index 0000000000..471332e3c1
--- /dev/null
+++ b/test/files/neg/bug4221.check
@@ -0,0 +1,6 @@
+bug4221.scala:8: error: type mismatch;
+ found : Unit
+ required: Wrapper[S]
+ def wrap[S <: Cl#Sub[S]](v: S): Wrapper[S] = {
+ ^
+one error found
diff --git a/test/files/neg/bug4221.scala b/test/files/neg/bug4221.scala
new file mode 100644
index 0000000000..0a8b8add18
--- /dev/null
+++ b/test/files/neg/bug4221.scala
@@ -0,0 +1,10 @@
+class Cl {
+ class Sub[TheSub <: Sub[TheSub]]
+}
+
+case class Wrapper[T](v: T)
+
+object O {
+ def wrap[S <: Cl#Sub[S]](v: S): Wrapper[S] = {
+ }
+}