diff options
author | Stephen Compall <scompall@nocandysw.com> | 2014-05-24 17:31:19 -0400 |
---|---|---|
committer | Stephen Compall <scompall@nocandysw.com> | 2014-05-24 17:31:19 -0400 |
commit | 9fc098dd0dcf1825ec55501716b4f2a0a6d197ae (patch) | |
tree | 7ef62fa8a9f0f017db7719c3875bba63fc13f0ed /test/files/run | |
parent | e948b39ca4df48b2acb0e972a2caf674c643a990 (diff) | |
download | scala-9fc098dd0dcf1825ec55501716b4f2a0a6d197ae.tar.gz scala-9fc098dd0dcf1825ec55501716b4f2a0a6d197ae.tar.bz2 scala-9fc098dd0dcf1825ec55501716b4f2a0a6d197ae.zip |
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.
Diffstat (limited to 'test/files/run')
-rw-r--r-- | test/files/run/t8346.check | 6 | ||||
-rw-r--r-- | test/files/run/t8346.scala | 34 |
2 files changed, 40 insertions, 0 deletions
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)}") +} |