summaryrefslogtreecommitdiff
path: root/test/files/pos
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2007-04-06 09:39:53 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2007-04-06 09:39:53 +0000
commitf96b6beefc08f56218ac68b37a4cecd757cb60ee (patch)
tree2001a44efae7ddd1699520d3855598ef13e30803 /test/files/pos
parent10a651a13c323366223160bfa1b4fe8a6e818d1d (diff)
downloadscala-f96b6beefc08f56218ac68b37a4cecd757cb60ee.tar.gz
scala-f96b6beefc08f56218ac68b37a4cecd757cb60ee.tar.bz2
scala-f96b6beefc08f56218ac68b37a4cecd757cb60ee.zip
adding test files from tcpoly branch without hi...
adding test files from tcpoly branch without history -- much faster this way, sorry
Diffstat (limited to 'test/files/pos')
-rw-r--r--test/files/pos/ksbug1.scala4
-rw-r--r--test/files/pos/nullary.scala20
-rw-r--r--test/files/pos/nullary_poly.scala10
-rw-r--r--test/files/pos/return_thistype.scala8
-rw-r--r--test/files/pos/tcpoly_boundedmonad.scala19
-rw-r--r--test/files/pos/tcpoly_bounds1.scala14
-rw-r--r--test/files/pos/tcpoly_gm.scala14
-rw-r--r--test/files/pos/tcpoly_higherorder_bound_method.scala3
-rw-r--r--test/files/pos/tcpoly_late_method_params.scala5
-rw-r--r--test/files/pos/tcpoly_method.scala6
-rw-r--r--test/files/pos/tcpoly_overloaded.scala25
-rw-r--r--test/files/pos/tcpoly_param_scoping.scala8
-rw-r--r--test/files/pos/tcpoly_poly.scala3
-rw-r--r--test/files/pos/tcpoly_return_overriding.scala13
-rw-r--r--test/files/pos/tcpoly_seq.scala175
-rw-r--r--test/files/pos/tcpoly_seq_typealias.scala143
-rw-r--r--test/files/pos/tcpoly_subst.scala4
-rw-r--r--test/files/pos/tcpoly_typesub.scala14
-rw-r--r--test/files/pos/tcpoly_variance.scala7
-rw-r--r--test/files/pos/tcpoly_wildcards.scala3
-rw-r--r--test/files/pos/typealias_dubious.scala15
-rw-r--r--test/files/pos/typealiases.scala20
22 files changed, 533 insertions, 0 deletions
diff --git a/test/files/pos/ksbug1.scala b/test/files/pos/ksbug1.scala
new file mode 100644
index 0000000000..b3e1631370
--- /dev/null
+++ b/test/files/pos/ksbug1.scala
@@ -0,0 +1,4 @@
+object test {
+ type z[a,b] = a => b
+ def f : z[int,int] = (i => i + 1)
+} \ No newline at end of file
diff --git a/test/files/pos/nullary.scala b/test/files/pos/nullary.scala
new file mode 100644
index 0000000000..22318d5143
--- /dev/null
+++ b/test/files/pos/nullary.scala
@@ -0,0 +1,20 @@
+abstract class NullaryTest[T, m[s]] {
+ def nullary: String = "a"
+ val x = nullary
+
+ def nullary2: T
+ val x2 = nullary2
+
+ def nullary3: m[T]
+ val x3 = nullary3
+}
+
+class Concrete extends NullaryTest[Int, List] {
+ def nullary2 = 1
+ def nullary3 = List(1,2,3)
+}
+
+object test {
+ (new Concrete).nullary2
+ (new Concrete).nullary3
+} \ No newline at end of file
diff --git a/test/files/pos/nullary_poly.scala b/test/files/pos/nullary_poly.scala
new file mode 100644
index 0000000000..9e3f239b36
--- /dev/null
+++ b/test/files/pos/nullary_poly.scala
@@ -0,0 +1,10 @@
+// test polymorphic nullary method calls
+class A {
+ // built-in
+ synchronized {}
+
+ val x: String = "a".asInstanceOf[String]
+
+ // user-defined:
+ def polyNullary[T]: List[T] = Nil
+} \ No newline at end of file
diff --git a/test/files/pos/return_thistype.scala b/test/files/pos/return_thistype.scala
new file mode 100644
index 0000000000..c0736c0ad9
--- /dev/null
+++ b/test/files/pos/return_thistype.scala
@@ -0,0 +1,8 @@
+// tests transformation of return type in typedTypeApply (see also tcpoly_gm.scala)
+class As {
+ class A {
+ def foo: A.this.type = bar.asInstanceOf[A.this.type]
+ def foo2: this.type = bar.asInstanceOf[this.type]
+ def bar: A = null
+ }
+}
diff --git a/test/files/pos/tcpoly_boundedmonad.scala b/test/files/pos/tcpoly_boundedmonad.scala
new file mode 100644
index 0000000000..ea19ae4c39
--- /dev/null
+++ b/test/files/pos/tcpoly_boundedmonad.scala
@@ -0,0 +1,19 @@
+trait Monad[T <: Bound[T], MyType[x <: Bound[x]], Bound[_]] {
+ def map[S <: Bound[S]](f: T => S): MyType[S]
+
+ def flatMap[S <: RBound[S], RContainer[x <: RBound[x]], RBound[_],
+ Result[x <: RBound[x]] <: Monad[x, RContainer, RBound]]
+ (f: T => Result[S]): Result[S]
+
+ def filter(p: T => Boolean): MyType[T]
+}
+
+class Set[T <: Ordered[T]] extends Monad[T, Set, Ordered] {
+ def map[S <: Ordered[S]](f: T => S): Set[S] = error("TODO")
+
+ def flatMap[S <: RBound[S], RContainer[x <: RBound[x]], RBound[_],
+ Result[x <: RBound[x]] <: Monad[x, RContainer, RBound]]
+ (f: T => Result[S]): Result[S] = error("TODO")
+
+ def filter(p: T => Boolean): Set[T] = error("TODO")
+} \ No newline at end of file
diff --git a/test/files/pos/tcpoly_bounds1.scala b/test/files/pos/tcpoly_bounds1.scala
new file mode 100644
index 0000000000..d74d3c975b
--- /dev/null
+++ b/test/files/pos/tcpoly_bounds1.scala
@@ -0,0 +1,14 @@
+class Foo[t[x]<: Pair[Int, x]]
+
+//
+class MyPair[z](a: Int, b: z) extends Pair[Int, z](a,b)
+
+object foo extends Foo[MyPair]
+
+
+trait Monad[m[x <: Bound[x]], Bound[x], a] // TODO: variances!
+trait ListMonad[a] extends Monad[List, Any, a]
+
+trait MyOrdered[a]
+trait MySet[x <: MyOrdered[x]]
+trait SetMonad[a <: MyOrdered[a]] extends Monad[MySet, MyOrdered, a] \ No newline at end of file
diff --git a/test/files/pos/tcpoly_gm.scala b/test/files/pos/tcpoly_gm.scala
new file mode 100644
index 0000000000..89b66cfba6
--- /dev/null
+++ b/test/files/pos/tcpoly_gm.scala
@@ -0,0 +1,14 @@
+trait Rep[a] {
+ def rep[m[x]]: m[a] // typedTypeApply must use asSeenFrom to adapt the return type
+ // since rep is called on x: Rep[t]
+ // a must become t
+}
+
+case class ShowBin[b](app: b => String)
+
+object foo {
+ def showBin[t](x: Rep[t], y: t): String = {
+ val r: ShowBin[t] = x.rep[ShowBin]
+ r.app(y)
+ }
+}
diff --git a/test/files/pos/tcpoly_higherorder_bound_method.scala b/test/files/pos/tcpoly_higherorder_bound_method.scala
new file mode 100644
index 0000000000..1e5cbf8092
--- /dev/null
+++ b/test/files/pos/tcpoly_higherorder_bound_method.scala
@@ -0,0 +1,3 @@
+trait SkolemisationOfHigherOrderBoundInMethod {
+ def method[A, N[X <: A], M[X <: N[A]]]: unit
+} \ No newline at end of file
diff --git a/test/files/pos/tcpoly_late_method_params.scala b/test/files/pos/tcpoly_late_method_params.scala
new file mode 100644
index 0000000000..2af0664618
--- /dev/null
+++ b/test/files/pos/tcpoly_late_method_params.scala
@@ -0,0 +1,5 @@
+trait Foo {
+ def flatMap[RT <: RBound[RT], RBound[_], Result[x <: RBound[x]]]: Result[RT]
+// bounds for RT& = >: scala.this.Nothing <: RBound&[RT&]
+ // bounds for x = >: scala.this.Nothing <: RBound&[x]
+} \ No newline at end of file
diff --git a/test/files/pos/tcpoly_method.scala b/test/files/pos/tcpoly_method.scala
new file mode 100644
index 0000000000..34dde904c3
--- /dev/null
+++ b/test/files/pos/tcpoly_method.scala
@@ -0,0 +1,6 @@
+trait Iterable[m[+x], +t] {
+ def flatMap[resColl[+x] <: Iterable[resColl, x], s](f: t => resColl[s]): resColl[s]
+
+ def foo[a[x]] = "a"
+ val x = foo[List]
+} \ No newline at end of file
diff --git a/test/files/pos/tcpoly_overloaded.scala b/test/files/pos/tcpoly_overloaded.scala
new file mode 100644
index 0000000000..47cb68a8bb
--- /dev/null
+++ b/test/files/pos/tcpoly_overloaded.scala
@@ -0,0 +1,25 @@
+trait Monad[T <: Bound[T], MyType[x <: Bound[x]], Bound[_]] {
+ def flatMap[S <: RBound[S], RContainer[x <: RBound[x]], RBound[_],
+ Result[x <: RBound[x]] <: Monad[x, RContainer, RBound]]
+ (f: T => Result[S]): Result[S]
+ def flatMap[S <: RBound[S], RContainer[x <: RBound[x]], RBound[_],
+ Result[x <: RBound[x]] <: Monad[x, RContainer, RBound]]
+ (f: T => Result[S], foo: String): Result[S]
+ def flatMap[S <: Bound[S]]
+ (f: T => MyType[S], foo: Int): MyType[S]
+}
+
+trait Test {
+ def moo: MList[Int]
+ class MList[T](el: T) extends Monad[T, List, Any] {
+ def flatMap[S <: RBound[S], RContainer[x <: RBound[x]], RBound[_],
+ Result[x <: RBound[x]] <: Monad[x, RContainer, RBound]]
+ (f: T => Result[S]): Result[S] = error("foo")
+ def flatMap[S <: RBound[S], RContainer[x <: RBound[x]], RBound[_],
+ Result[x <: RBound[x]] <: Monad[x, RContainer, RBound]]
+ (f: T => Result[S], foo: String): Result[S] = error("foo")
+ def flatMap[S]
+ (f: T => List[S], foo: Int): List[S] = error("foo")
+ }
+ val l: MList[String] = moo.flatMap[String, List, Any, MList]((x: Int) => new MList("String"))
+} \ No newline at end of file
diff --git a/test/files/pos/tcpoly_param_scoping.scala b/test/files/pos/tcpoly_param_scoping.scala
new file mode 100644
index 0000000000..1019fdfaf2
--- /dev/null
+++ b/test/files/pos/tcpoly_param_scoping.scala
@@ -0,0 +1,8 @@
+trait FOO[B, m[A <: B]]
+trait FOO2[A <: B, B]
+trait FOO3[m[A <: B], B]
+
+class Test {
+ def foo[a[x]] = "a"
+}
+//trait Idiom[idi[x]] { def foo: idi[Int]} \ No newline at end of file
diff --git a/test/files/pos/tcpoly_poly.scala b/test/files/pos/tcpoly_poly.scala
new file mode 100644
index 0000000000..1ba04e29df
--- /dev/null
+++ b/test/files/pos/tcpoly_poly.scala
@@ -0,0 +1,3 @@
+class Monad[m[x]]
+
+object ml extends Monad[List]
diff --git a/test/files/pos/tcpoly_return_overriding.scala b/test/files/pos/tcpoly_return_overriding.scala
new file mode 100644
index 0000000000..cc7dd55cec
--- /dev/null
+++ b/test/files/pos/tcpoly_return_overriding.scala
@@ -0,0 +1,13 @@
+trait Generic[g[x]] {
+ def unit: g[Unit]
+}
+
+trait Rep[t] {
+ def rep[m[x]](implicit gen: Generic[m]): m[t]
+}
+
+// testing that the return type is also transformed when checking overriding
+// + that substitution (of types&symbols) preserves isHigherKinded when replacing a higher-kinded type with another one
+object foo extends Rep[Unit] {
+ def rep[g[x]](implicit gen: Generic[g]): g[Unit]= gen.unit
+} \ No newline at end of file
diff --git a/test/files/pos/tcpoly_seq.scala b/test/files/pos/tcpoly_seq.scala
new file mode 100644
index 0000000000..85563488fd
--- /dev/null
+++ b/test/files/pos/tcpoly_seq.scala
@@ -0,0 +1,175 @@
+package examples.tcpoly.collection;
+
+trait HOSeq {
+ // an internal interface that encapsulates the accumulation of elements (of type elT) to produce
+ // a structure of type coll[elT] -- different kinds of collections should provide different implicit
+ // values implementing this interface, in order to provide more performant ways of building that structure
+ trait Accumulator[+coll[x], elT] {
+ def += (el: elT): Unit
+ def result: coll[elT]
+ }
+
+
+ // Iterable abstracts over the type of its structure as well as its elements (see PolyP's Bifunctor)
+ // m[x] is intentionally unbounded: fold can then be defined nicely
+ // variance: if we write m[+x] instead of +m[+x], x is an invariant position because its enclosing type
+ // is an invariant position -- should probably rule that out?
+ trait Iterable[+m[+x], +t] {
+ //def unit[a](orig: a): m[a]
+ def elements: Iterator[t]
+
+ // construct an empty accumulator that will produce the same structure as this iterable, with elements of type t
+ def accumulator[t]: Accumulator[m, t]
+
+ def filter(p: t => Boolean): m[t] = {
+ val buf = accumulator[t]
+ val elems = elements
+ while (elems.hasNext) { val x = elems.next; if (p(x)) buf += x }
+ buf.result
+ }
+
+ def map[s](f: t => s): m[s] = {
+ val buf = accumulator[s]
+ val elems = elements
+ while (elems.hasNext) buf += f(elems.next)
+ buf.result
+ }
+
+ // flatMap is a more specialized map, it only works if the mapped function produces Iterable values,
+ // which are then added to the result one by one
+ // the compiler should be able to find the right accumulator (implicit buf) to build the result
+ // to get concat, resColl = SingletonIterable, f = unit for SingletonIterable
+ def flatMap[resColl[+x] <: Iterable[resColl, x], s](f: t => resColl[s])(implicit buf: Accumulator[resColl, s]): resColl[s] = {
+ // TODO: would a viewbound for resColl[x] be better?
+ // -- 2nd-order type params are not yet in scope in view bound
+ val elems = elements
+ while (elems.hasNext) {
+ val elemss: Iterator[s] = f(elems.next).elements
+ while (elemss.hasNext) buf += elemss.next
+ }
+ buf.result
+ }
+ }
+
+ final class ListBuffer[A] {
+ private var start: List[A] = Nil
+ private var last: ::[A] = _
+ private var exported: boolean = false
+
+ /** Appends a single element to this buffer.
+ *
+ * @param x the element to append.
+ */
+ def += (x: A): unit = {
+ if (exported) copy
+ if (start.isEmpty) {
+ last = new HOSeq.this.:: (x, Nil)
+ start = last
+ } else {
+ val last1 = last
+ last = new HOSeq.this.:: (x, null) // hack: ::'s tail will actually be last
+ //last1.tl = last
+ }
+ }
+
+ /** Converts this buffer to a list
+ */
+ def toList: List[A] = {
+ exported = !start.isEmpty
+ start
+ }
+
+ /** Clears the buffer contents.
+ */
+ def clear: unit = {
+ start = Nil
+ exported = false
+ }
+
+ /** Copy contents of this buffer */
+ private def copy = {
+ var cursor = start
+ val limit = last.tail
+ clear
+ while (cursor ne limit) {
+ this += cursor.head
+ cursor = cursor.tail
+ }
+ }
+ }
+
+ implicit def listAccumulator[elT]: Accumulator[List, elT] = new Accumulator[List, elT] {
+ private[this] val buff = new ListBuffer[elT]
+ def += (el: elT): Unit = buff += el
+ def result: List[elT] = buff.toList
+ }
+
+ trait List[+t] extends Iterable[List, t] {
+ def head: t
+ def tail: List[t]
+ def isEmpty: Boolean
+ def elements: Iterator[t] = new Iterator[t] {
+ var these = List.this
+ def hasNext: Boolean = !these.isEmpty
+ def next: t =
+ if (!hasNext)
+ throw new NoSuchElementException("next on empty Iterator")
+ else {
+ val result = these.head; these = these.tail; result
+ }
+ }
+ // construct an empty accumulator that will produce the same structure as this iterable, with elements of type t
+ def accumulator[t]: Accumulator[List, t] = listAccumulator[t]
+ }
+
+ // TODO: the var tl approach does not seem to work because subtyping isn't fully working yet
+ final case class ::[+b](hd: b, private val tl: List[b]) extends List[b] {
+ def head = hd
+ def tail = if(tl==null) this else tl // hack
+ override def isEmpty: boolean = false
+ }
+
+ case object Nil extends List[Nothing] {
+ def isEmpty = true
+ def head: Nothing =
+ throw new NoSuchElementException("head of empty list")
+ def tail: List[Nothing] =
+ throw new NoSuchElementException("tail of empty list")
+ }
+}
+
+
+
+// misc signatures collected from mailing list / library code:
+ /*override def flatMap[B](f: A => Iterable[B]): Set[B]
+ final override def flatMap[b](f: Any => Iterable[b]): Array[b]
+ def flatMap[b](f: a => Parser[b]) = new Parser[b]
+ override def flatMap[b](f: a => Iterable[b]): List[b]
+
+
+ MapResult[K] <: Seq[K]
+ FilterResult <: Seq[T]
+ Concat <: Seq[T]
+ Subseq <: Seq[T]
+
+
+ def map[K](f: T=>K): MapResult[K]
+ def filter(f: T=>Boolean): FilterResult
+ def subseq(from: int, to: int): Subseq
+ def flatMap[S <: Seq[K], K](f: T => S): S#Concat // legal?
+ def concat(others: Seq[T]): Concat
+ */
+
+/*trait Iterator[t] {
+ // @post hasAdvanced implies hasNext
+ // model def hasAdvanced: Boolean
+
+ def hasNext: Boolean // pure
+
+ // @pre hasAdvanced
+ def current: t // pure
+
+ // @pre hasNext
+ // @post hasAdvanced
+ def advance: Unit
+}*/ \ No newline at end of file
diff --git a/test/files/pos/tcpoly_seq_typealias.scala b/test/files/pos/tcpoly_seq_typealias.scala
new file mode 100644
index 0000000000..0498c3b2f6
--- /dev/null
+++ b/test/files/pos/tcpoly_seq_typealias.scala
@@ -0,0 +1,143 @@
+package examples.tcpoly.collection;
+
+trait HOSeq {
+ // an internal interface that encapsulates the accumulation of elements (of type elT) to produce
+ // a structure of type coll[elT] -- different kinds of collections should provide different implicit
+ // values implementing this interface, in order to provide more performant ways of building that structure
+ trait Accumulator[+coll[x], elT] {
+ def += (el: elT): Unit
+ def result: coll[elT]
+ }
+
+
+ // Iterable abstracts over the type of its structure as well as its elements (see PolyP's Bifunctor)
+ // m[x] is intentionally unbounded: fold can then be defined nicely
+ // variance: if we write m[+x] instead of +m[+x], x is an invariant position because its enclosing type
+ // is an invariant position -- should probably rule that out?
+ trait Iterable[+t] {
+ type m[+x]
+
+ //def unit[a](orig: a): m[a]
+ def elements: Iterator[t]
+
+ // construct an empty accumulator that will produce the same structure as this iterable, with elements of type t
+ def accumulator[t]: Accumulator[m, t]
+
+ def filter(p: t => Boolean): m[t] = {
+ val buf = accumulator[t]
+ val elems = elements
+ while (elems.hasNext) { val x = elems.next; if (p(x)) buf += x }
+ buf.result
+ }
+
+ def map[s](f: t => s): m[s] = {
+ val buf = accumulator[s]
+ val elems = elements
+ while (elems.hasNext) buf += f(elems.next)
+ buf.result
+ }
+
+ // flatMap is a more specialized map, it only works if the mapped function produces Iterable values,
+ // which are then added to the result one by one
+ // the compiler should be able to find the right accumulator (implicit buf) to build the result
+ // to get concat, resColl = SingletonIterable, f = unit for SingletonIterable
+ def flatMap[resColl[+x] <: Iterable[x], s](f: t => resColl[s])(implicit buf: Accumulator[resColl, s]): resColl[s] = {
+ // TODO: would a viewbound for resColl[x] be better?
+ // -- 2nd-order type params are not yet in scope in view bound
+ val elems = elements
+ while (elems.hasNext) {
+ val elemss: Iterator[s] = f(elems.next).elements
+ while (elemss.hasNext) buf += elemss.next
+ }
+ buf.result
+ }
+ }
+
+ final class ListBuffer[A] {
+ private var start: List[A] = Nil
+ private var last: ::[A] = _
+ private var exported: boolean = false
+
+ /** Appends a single element to this buffer.
+ *
+ * @param x the element to append.
+ */
+ def += (x: A): unit = {
+ if (exported) copy
+ if (start.isEmpty) {
+ last = new HOSeq.this.:: (x, Nil)
+ start = last
+ } else {
+ val last1 = last
+ last = new HOSeq.this.:: (x, null) // hack: ::'s tail will actually be last
+ //last1.tl = last
+ }
+ }
+
+ /** Converts this buffer to a list
+ */
+ def toList: List[A] = {
+ exported = !start.isEmpty
+ start
+ }
+
+ /** Clears the buffer contents.
+ */
+ def clear: unit = {
+ start = Nil
+ exported = false
+ }
+
+ /** Copy contents of this buffer */
+ private def copy = {
+ var cursor = start
+ val limit = last.tail
+ clear
+ while (cursor ne limit) {
+ this += cursor.head
+ cursor = cursor.tail
+ }
+ }
+ }
+
+ implicit def listAccumulator[elT]: Accumulator[List, elT] = new Accumulator[List, elT] {
+ private[this] val buff = new ListBuffer[elT]
+ def += (el: elT): Unit = buff += el
+ def result: List[elT] = buff.toList
+ }
+
+ trait List[+t] extends Iterable[t] {
+ type m[+x] = List[x]
+
+ def head: t
+ def tail: List[t]
+ def isEmpty: Boolean
+ def elements: Iterator[t] = new Iterator[t] {
+ var these = List.this
+ def hasNext: Boolean = !these.isEmpty
+ def next: t =
+ if (!hasNext)
+ throw new NoSuchElementException("next on empty Iterator")
+ else {
+ val result = these.head; these = these.tail; result
+ }
+ }
+ // construct an empty accumulator that will produce the same structure as this iterable, with elements of type t
+ def accumulator[t]: Accumulator[List, t] = listAccumulator[t]
+ }
+
+ // TODO: the var tl approach does not seem to work because subtyping isn't fully working yet
+ final case class ::[+b](hd: b, private val tl: List[b]) extends List[b] {
+ def head = hd
+ def tail = if(tl==null) this else tl // hack
+ override def isEmpty: boolean = false
+ }
+
+ case object Nil extends List[Nothing] {
+ def isEmpty = true
+ def head: Nothing =
+ throw new NoSuchElementException("head of empty list")
+ def tail: List[Nothing] =
+ throw new NoSuchElementException("tail of empty list")
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/tcpoly_subst.scala b/test/files/pos/tcpoly_subst.scala
new file mode 100644
index 0000000000..af474585e9
--- /dev/null
+++ b/test/files/pos/tcpoly_subst.scala
@@ -0,0 +1,4 @@
+object test {
+ def make[m[x], b]: m[b] = error("foo")
+ val lst: List[Int] = make[List, Int]
+} \ No newline at end of file
diff --git a/test/files/pos/tcpoly_typesub.scala b/test/files/pos/tcpoly_typesub.scala
new file mode 100644
index 0000000000..bb29d88bd9
--- /dev/null
+++ b/test/files/pos/tcpoly_typesub.scala
@@ -0,0 +1,14 @@
+// contributed by Lauri Alanko
+trait TypeSub {
+ type l
+ type u
+ def castSub[f[+x]](fl : f[l]) : f[u]
+ def castSuper[f[-x]](fu : f[u]) : f[l] = {
+ type c[+y] = f[y] => f[l]
+ castSub[c]{ fl : f[l] => fl }(fu)
+ }
+ def castValue[t](lt : l with t) : u with t = {
+ type c[+y] = y with t
+ castSub[c](lt)
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/tcpoly_variance.scala b/test/files/pos/tcpoly_variance.scala
new file mode 100644
index 0000000000..9e034ef97e
--- /dev/null
+++ b/test/files/pos/tcpoly_variance.scala
@@ -0,0 +1,7 @@
+class A[m[+x]] {
+ def str: m[Object] = error("foo")
+}
+
+class B[m[+x]] extends A[m] {
+ override def str: m[String] = error("foo")
+} \ No newline at end of file
diff --git a/test/files/pos/tcpoly_wildcards.scala b/test/files/pos/tcpoly_wildcards.scala
new file mode 100644
index 0000000000..eed0e6f685
--- /dev/null
+++ b/test/files/pos/tcpoly_wildcards.scala
@@ -0,0 +1,3 @@
+trait test[b[_,_]] {
+ def moo[a[_, _]] = error("a")
+} \ No newline at end of file
diff --git a/test/files/pos/typealias_dubious.scala b/test/files/pos/typealias_dubious.scala
new file mode 100644
index 0000000000..98df5c1290
--- /dev/null
+++ b/test/files/pos/typealias_dubious.scala
@@ -0,0 +1,15 @@
+class MailBox {
+ //class Message
+ type Message = AnyRef
+}
+
+abstract class Actor {
+ private val in = new MailBox
+
+ def send(msg: in.Message) = error("foo")
+
+ def unstable: Actor = error("foo")
+
+ def dubiousSend(msg: MailBox#Message) =
+ unstable.send(msg) // in.Message becomes unstable.Message, but that's ok since Message is a concrete type member
+} \ No newline at end of file
diff --git a/test/files/pos/typealiases.scala b/test/files/pos/typealiases.scala
new file mode 100644
index 0000000000..c32a3e3a78
--- /dev/null
+++ b/test/files/pos/typealiases.scala
@@ -0,0 +1,20 @@
+package foo
+
+trait Test[T] {
+ type Check[T] = Array[T] => Unit;
+ type MyPair[S] = Pair[T, S]
+
+ val pair1: Pair[T, Int]
+ val pair: MyPair[Int] = pair1
+
+ def check(xs: Array[T], c: Check[T]) = c(xs)
+ def check2[S](xs: Array[S], c: Check[S]) = c(xs)
+}
+
+object main extends Test[Int] {
+ val pair1 = (1,1)
+
+ implicit def topair(x: Int): Pair[Int, Int] = (x,x)
+ val pair2: MyPair[Int] = 1
+ val x: short = 1
+} \ No newline at end of file