From c0f03d837c9af04f404e800ce6fbeb65d1eac38a Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 14 Sep 2010 12:15:35 +0000 Subject: 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 --- src/compiler/scala/tools/nsc/typechecker/Infer.scala | 5 ++++- test/files/neg/t3692.check | 14 ++++++++++++++ test/files/neg/t3692.scala | 17 +++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test/files/neg/t3692.check create mode 100644 test/files/neg/t3692.scala 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 java.lang.Integer instead + case m0: Map[Int, Int] => new java.util.HashMap[Integer, Integer] + ^ +t3692.scala:12: warning: type Integer in package scala is deprecated: use java.lang.Integer instead + case m1: Map[Int, V] => new java.util.HashMap[Integer, V] + ^ +t3692.scala:13: warning: type Integer in package scala is deprecated: use java.lang.Integer 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 -- cgit v1.2.3