summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2010-09-14 12:15:35 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2010-09-14 12:15:35 +0000
commitc0f03d837c9af04f404e800ce6fbeb65d1eac38a (patch)
tree67d603a233023c8204c6d0665506af8e03fcf884
parent4c47e9435d8872a30f579ed451293d4772b95c31 (diff)
downloadscala-c0f03d837c9af04f404e800ce6fbeb65d1eac38a.tar.gz
scala-c0f03d837c9af04f404e800ce6fbeb65d1eac38a.tar.bz2
scala-c0f03d837c9af04f404e800ce6fbeb65d1eac38a.zip
closes #3692: make instantiateTypeVar more care...
closes #3692: make instantiateTypeVar more careful so it does not change T's info to >: T <: T. review by odersky
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala5
-rw-r--r--test/files/neg/t3692.check14
-rw-r--r--test/files/neg/t3692.scala17
3 files changed, 35 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index d4979b0589..0c81bb3887 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -1250,6 +1250,8 @@ trait Infer {
solve(tvars1, tvars1 map (_.origin.typeSymbol), tvars1 map (x => COVARIANT), false)
}
+ // this is quite nasty: it destructively changes the info of the syms of e.g., method type params (see #3692, where the type param T's bounds were set to >: T <: T, so that parts looped)
+ // the changes are rolled back by restoreTypeBounds, but might be unintentially observed in the mean time
def instantiateTypeVar(tvar: TypeVar) {
val tparam = tvar.origin.typeSymbol
if (false &&
@@ -1263,7 +1265,8 @@ trait Infer {
} else {
val (lo, hi) = instBounds(tvar)
if (lo <:< hi) {
- if (!((lo <:< tparam.info.bounds.lo) && (tparam.info.bounds.hi <:< hi))) {
+ if (!((lo <:< tparam.info.bounds.lo) && (tparam.info.bounds.hi <:< hi)) // bounds were improved
+ && tparam != lo.typeSymbolDirect && tparam != hi.typeSymbolDirect) { // don't create illegal cycles
context.nextEnclosing(_.tree.isInstanceOf[CaseDef]).pushTypeBounds(tparam)
tparam setInfo TypeBounds(lo, hi)
if (settings.debug.value) log("new bounds of " + tparam + " = " + tparam.info)
diff --git a/test/files/neg/t3692.check b/test/files/neg/t3692.check
new file mode 100644
index 0000000000..ce89a6563d
--- /dev/null
+++ b/test/files/neg/t3692.check
@@ -0,0 +1,14 @@
+t3692.scala:11: warning: type Integer in package scala is deprecated: use <code>java.lang.Integer</code> instead
+ case m0: Map[Int, Int] => new java.util.HashMap[Integer, Integer]
+ ^
+t3692.scala:12: warning: type Integer in package scala is deprecated: use <code>java.lang.Integer</code> instead
+ case m1: Map[Int, V] => new java.util.HashMap[Integer, V]
+ ^
+t3692.scala:13: warning: type Integer in package scala is deprecated: use <code>java.lang.Integer</code> instead
+ case m2: Map[T, Int] => new java.util.HashMap[T, Integer]
+ ^
+t3692.scala:13: error: unreachable code
+ case m2: Map[T, Int] => new java.util.HashMap[T, Integer]
+ ^
+three warnings found
+one error found
diff --git a/test/files/neg/t3692.scala b/test/files/neg/t3692.scala
new file mode 100644
index 0000000000..78b0e4b843
--- /dev/null
+++ b/test/files/neg/t3692.scala
@@ -0,0 +1,17 @@
+object ManifestTester {
+ def main(args: Array[String]) = {
+ val map = Map("John" -> 1, "Josh" -> 2)
+ new ManifestTester().toJavaMap(map)
+ }
+}
+
+class ManifestTester {
+ private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = {
+ map match {
+ case m0: Map[Int, Int] => new java.util.HashMap[Integer, Integer]
+ case m1: Map[Int, V] => new java.util.HashMap[Integer, V]
+ case m2: Map[T, Int] => new java.util.HashMap[T, Integer]
+ case _ => new java.util.HashMap[T, V]
+ }
+ }
+} \ No newline at end of file