From 9fc098dd0dcf1825ec55501716b4f2a0a6d197ae Mon Sep 17 00:00:00 2001 From: Stephen Compall Date: Sat, 24 May 2014 17:31:19 -0400 Subject: SI-8346: Rebuild invariant sets in #toSet, avoiding CCE. SI-3953 caused several types of sets' operations to trivially throw `ClassCastException` after using inherited covariant #toSet method, by doing an unchecked cast that is only safe for intrinsically covariant set data structures like `HashSet`, but totally unsafe for others like `TreeSet` or `Enumeration.ValueSet`. This change moves the cast to the leaves of the class hierarchy where that is safe, and incidentally undeprecates overriding Set#toSet. --- test/files/run/t8346.check | 6 ++++++ test/files/run/t8346.scala | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 test/files/run/t8346.check create mode 100644 test/files/run/t8346.scala (limited to 'test') diff --git a/test/files/run/t8346.check b/test/files/run/t8346.check new file mode 100644 index 0000000000..1ba5c31abe --- /dev/null +++ b/test/files/run/t8346.check @@ -0,0 +1,6 @@ +BitSet: List(invariant, invariant, invariant, invariant) +HashSet: List(covariant (true), covariant (true), covariant (true), covariant (true)) +ListSet: List(covariant (true), covariant (true), covariant (true), covariant (true)) +SortedSet: List(invariant, invariant, invariant, invariant) +TreeSet: List(invariant, invariant, invariant, invariant) +ValueSet: invariant diff --git a/test/files/run/t8346.scala b/test/files/run/t8346.scala new file mode 100644 index 0000000000..5f3df84174 --- /dev/null +++ b/test/files/run/t8346.scala @@ -0,0 +1,34 @@ +object Test extends App { + import reflect.ClassTag + + object SomeEnum extends Enumeration { + val one, two, three, four = Value + } + + def sctor[A <: Set[Int]](f: Int => A)(implicit A: ClassTag[A]) + : (String, Int => Set[Int]) = + (A.runtimeClass.getSimpleName, f) + + val inits: Seq[(String, Int => Set[Int])] = { + import collection.immutable.{Seq => _, _} + Seq(sctor(BitSet(_)), + sctor(HashSet(_)), + sctor(ListSet(_)), + sctor(SortedSet(_)), + sctor(TreeSet(_))) + } + + def sVarInfo[A](sa: Set[A]): String = { + val saa = sa.toSet[Any] + if (sa eq saa) s"""covariant (${(saa + "hi") contains "hi"})""" + else "invariant" + } + + inits foreach {case (name, singleton) => + print(s"${name}: ") + val one = singleton(1) + println(Seq(2,3,4).scanLeft(one)(_ + _) map sVarInfo toList) + } + + println(s"ValueSet: ${sVarInfo(SomeEnum.values)}") +} -- cgit v1.2.3