diff options
author | Paul Phillips <paulp@improving.org> | 2013-01-02 07:36:58 -0800 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-01-28 15:05:10 -0800 |
commit | f6d90a8a2502c0e1f0ecf72a2fd4258c4f52ec84 (patch) | |
tree | e98828f2ddf4402f7637af3fde85c5fc5e9e5ddf /test/files/neg/t5378.scala | |
parent | cc3b9a23ebb453b827197e5ab5cba46a9e770f0c (diff) | |
download | scala-f6d90a8a2502c0e1f0ecf72a2fd4258c4f52ec84.tar.gz scala-f6d90a8a2502c0e1f0ecf72a2fd4258c4f52ec84.tar.bz2 scala-f6d90a8a2502c0e1f0ecf72a2fd4258c4f52ec84.zip |
[backport] SI-5378, unsoundness with type bounds in refinements.
As the comment says:
Not enough to look for abstract types; have to recursively check
the bounds of each abstract type for more abstract types. Almost
certainly there are other exploitable type soundness bugs which
can be seen by bounding a type parameter by an abstract type which
itself is bounded by an abstract type.
SPECIAL: BUY ONE UNSOUNDNESS, GET ONE FREE
In refinement types, only the first parameter list of methods
was being analyzed for unsound uses of abstract types. Second
parameter list and beyond had free unsoundness reign. That bug
as well is fixed here.
Diffstat (limited to 'test/files/neg/t5378.scala')
-rw-r--r-- | test/files/neg/t5378.scala | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/test/files/neg/t5378.scala b/test/files/neg/t5378.scala new file mode 100644 index 0000000000..fa6afa02be --- /dev/null +++ b/test/files/neg/t5378.scala @@ -0,0 +1,54 @@ +import scala.language.reflectiveCalls + +class Coll[+T] { + type A1 <: T + type A2 <: A1 + + def contains = new { def apply[T1 <: T](value: T1) = ??? } + def contains1 = new { def apply[T1 <: A1](value: T1) = ??? } + def contains2 = new { def apply[T1 <: A2](value: T1) = ??? } + def contains3 = { + trait Bippy { + type B1 <: T + type B2 <: B1 + } + new Bippy { def apply[T1 <: T](value: T1) = ??? } + new Bippy { def apply[T1 <: B1](value: T1) = ??? } + new Bippy { def apply[T1 <: B2](value: T1) = ??? } + new Bippy { + type B3 = B2 + type B4 = List[B2] + def apply1[T1 <: B3](value: T1) = ??? + def apply2[T1 <: B4](value: T1) = ??? + def apply3(value: B3) = ??? + def apply4(value: B4) = value.head + } + } + def contains4 = new { + def apply1(s: String)(x: Int)(value: T) = ??? + def apply2[T1 <: T](s: String)(x: Int)(value: T1) = ??? + } + def containsOk = { + trait Bippy { + type B1 <: AnyRef + type B2 <: B1 + } + new Bippy { def apply[T1 <: AnyRef](value: T1) = ??? } + new Bippy { type B1 = String ; def apply[T1 <: B1](value: T1) = ??? } + new Bippy { type B2 = String ; def apply[T1 <: B2](value: T1) = ??? } + } +} + +object Test { + def main(args: Array[String]): Unit = { + val xs = new Coll[List[String]] + val ys: Coll[Traversable[String]] = xs + + println(ys contains Nil) + // java.lang.NoSuchMethodException: Coll$$anon$1.apply(scala.collection.Traversable) + // at java.lang.Class.getMethod(Class.java:1605) + // at Test$.reflMethod$Method1(a.scala:14) + // at Test$.main(a.scala:14) + // at Test.main(a.scala) + } +} |