diff options
author | odersky <odersky@gmail.com> | 2016-04-06 11:23:40 +0200 |
---|---|---|
committer | odersky <odersky@gmail.com> | 2016-04-06 11:23:40 +0200 |
commit | 474d99792fd330f59f7b75b45bee80f52ce65082 (patch) | |
tree | 325b3982993c9726e60f94d2b57d73e28c229ad4 /tests | |
parent | 1a6eedd4fb714b3769bbb07eb8636995f961c4a6 (diff) | |
parent | f675ad9507089f8b912357fab86740653c1b8789 (diff) | |
download | dotty-474d99792fd330f59f7b75b45bee80f52ce65082.tar.gz dotty-474d99792fd330f59f7b75b45bee80f52ce65082.tar.bz2 dotty-474d99792fd330f59f7b75b45bee80f52ce65082.zip |
Merge pull request #1186 from dotty-staging/fix-#1185
Improvements to cyclic checking, avoidance, named parameters
Diffstat (limited to 'tests')
-rw-r--r-- | tests/neg/named-params.scala | 3 | ||||
-rw-r--r-- | tests/pending/pos/i1181.scala | 12 | ||||
-rw-r--r-- | tests/pos/CollectionStrawMan3.scala | 20 | ||||
-rw-r--r-- | tests/pos/flowops.scala | 31 | ||||
-rw-r--r-- | tests/pos/flowops1.scala | 39 | ||||
-rw-r--r-- | tests/pos/named-params.scala | 48 |
6 files changed, 141 insertions, 12 deletions
diff --git a/tests/neg/named-params.scala b/tests/neg/named-params.scala index 9ef4ed066..5a2375b15 100644 --- a/tests/neg/named-params.scala +++ b/tests/neg/named-params.scala @@ -32,3 +32,6 @@ object Test { val z5 = d2[Elem = Int][Value = String](1) //error // error } + + + diff --git a/tests/pending/pos/i1181.scala b/tests/pending/pos/i1181.scala new file mode 100644 index 000000000..057c938d3 --- /dev/null +++ b/tests/pending/pos/i1181.scala @@ -0,0 +1,12 @@ +object Test { + def foo[M[_]](x: M[Int]) = x + + type Alias[A] = (A, A) + val x: Alias[Int] = (1, 2) + + foo[Alias](x) // ok + foo(x) // ok in scalac but fails in dotty with: + // error: type mismatch: + // found : (Int, Int) + // required: M[Int] +} diff --git a/tests/pos/CollectionStrawMan3.scala b/tests/pos/CollectionStrawMan3.scala index 47d3b52d6..c21a73f00 100644 --- a/tests/pos/CollectionStrawMan3.scala +++ b/tests/pos/CollectionStrawMan3.scala @@ -114,13 +114,13 @@ object CollectionStrawMan1 { /* --------- Concrete collection types ------------------------------- */ /** Concrete collection type: List */ - sealed trait List[+A] extends Seq[A] with FromIterator[List] { + sealed trait List[type +Elem] extends Seq[Elem] with FromIterator[List] { def isEmpty: Boolean - def head: A - def tail: List[A] - def iterator = new ListIterator[A](this) + def head: Elem + def tail: List[Elem] + def iterator = new ListIterator[Elem](this) def fromIterator[B](it: Iterator[B]): List[B] = List.fromIterator(it) - def apply(i: Int): A = { + def apply(i: Int): Elem = { require(!isEmpty) if (i == 0) head else tail.apply(i - 1) } @@ -155,17 +155,17 @@ object CollectionStrawMan1 { } /** Concrete collection type: ArrayBuffer */ - class ArrayBuffer[A] private (initElems: Array[AnyRef], initLength: Int) extends Seq[A] with FromIterator[ArrayBuffer] { + class ArrayBuffer[type Elem] private (initElems: Array[AnyRef], initLength: Int) extends Seq[Elem] with FromIterator[ArrayBuffer] { def this() = this(new Array[AnyRef](16), 0) private var elems: Array[AnyRef] = initElems private var start = 0 private var limit = initLength - def apply(i: Int) = elems(start + i).asInstanceOf[A] + def apply(i: Int) = elems(start + i).asInstanceOf[Elem] def length = limit - start - def iterator = new ArrayBufferIterator[A](elems, start, length) + def iterator = new ArrayBufferIterator[Elem](elems, start, length) def fromIterator[B](it: Iterator[B]): ArrayBuffer[B] = ArrayBuffer.fromIterator(it) - def +=(elem: A): this.type = { + def +=(elem: Elem): this.type = { if (limit == elems.length) { if (start > 0) { Array.copy(elems, start, elems, 0, length) @@ -213,7 +213,7 @@ object CollectionStrawMan1 { } /** Concrete collection type: View */ - class View[+A](it: => Iterator[A]) extends CanIterate[A] { + class View[type +Elem](it: => Iterator[Elem]) extends CanIterate[Elem] { def iterator = it } diff --git a/tests/pos/flowops.scala b/tests/pos/flowops.scala new file mode 100644 index 000000000..6aead26be --- /dev/null +++ b/tests/pos/flowops.scala @@ -0,0 +1,31 @@ +object Test { + import language.higherKinds + + class NotUsed + + trait FO[+Out, +Mat] { self => + type Repr[+O] <: FO[O, Mat] { + type Repr[+OO] = self.Repr[OO] + } + def map[T](f: Out => T): Repr[T] = ??? + } + + class Source[+O, +M] extends FO[O, M] { + type Repr[+OO] <: Source[OO, M] + } + + class Flow[-I, +O, +M] extends FO[O, M] { + type Repr[+OO] <: Flow[I, OO, M] + } + + implicit class x[O, M, F[o, m] <: FO[o, m]](val f: F[O, M]) extends AnyVal { + def xx(i: Int): f.Repr[O] = f.map(identity) + } + + type IntFlow[O, M] = Flow[Int, O, M] + + val s1 = new Source[Int, NotUsed].xx(12) + val s2: Source[Int, NotUsed] = s1 + val f1 = x[Int, NotUsed, IntFlow](new Flow[Int, Int, NotUsed]).xx(12) + val f2: Flow[Int, Int, NotUsed] = f1 +} diff --git a/tests/pos/flowops1.scala b/tests/pos/flowops1.scala new file mode 100644 index 000000000..649a9b18c --- /dev/null +++ b/tests/pos/flowops1.scala @@ -0,0 +1,39 @@ +object Test { + class NotUsed + + trait FO[type +Out, type +Mat] { self => + type Repr <: FO[Mat = self.Mat] { + type Repr = self.Repr + } + def map[T](f: Out => T): Repr[Out = T] = ??? + } + + class Source[type +Out, type +Mat] extends FO[Out, Mat] { self => + type Repr <: Source[Mat = self.Mat] + } + + class Flow[type -In, type +Out, type +Mat] extends FO[Out, Mat] { self => + type Repr <: Flow[In = self.In, Mat = self.Mat] + } + + implicit class x[O, M, F <: FO](val f: F[Out = O, Mat = M]) extends AnyVal { + def xx(i: Int): f.Repr[Out = O] = f.map(identity) + } + + class xalt[O, M, F <: FO](val f: F[Out = O, Mat = M]) extends AnyVal { + def xx(i: Int): FO[Out = O, Mat = M] = ??? + } + + val s1 = new Source[Int, NotUsed].xx(12) + val s2: Source[Int, NotUsed] = s1 + val f1 = x[Int, NotUsed, Flow[In = Int]](new Flow[Int, Int, NotUsed]).xx(12) + val f2: Flow[Int, Int, NotUsed] = f1 + + + val f3 = x(new Flow[Int, Int, NotUsed]).xx(12) + val f4: Flow[Int, Int, NotUsed] = f3 + val f5 = new Flow[Int, Int, NotUsed].xx(12) + val f6: Flow[Int, Int, NotUsed] = f5 + val f7 = new xalt(new Flow[Int, Int, NotUsed]).xx(12) + val f8: FO[Int, NotUsed] = f7 +} diff --git a/tests/pos/named-params.scala b/tests/pos/named-params.scala index bcd64ea4b..3fab24cd2 100644 --- a/tests/pos/named-params.scala +++ b/tests/pos/named-params.scala @@ -29,9 +29,39 @@ object Test { val z3 = d2[E = Int](1) val z4 = d2[V = Int]("AAA") val z5 = d2[E = Int][V = String](1) + +// Testing type inference + + def f[X <: C](x: X[Int, Int]): X[String, String] = ??? + val arg1: C[Int, Int] = ??? + val res1 = f(arg1) + val chk1: C[String, String] = res1 + + class C1[type Elem, type Value](x: Elem) extends C[Elem, Value](x) + class CC extends C1[Int, Int](1) + val arg2: CC = ??? + val res2 = f(arg2) + val chk2: C[String, String] = res2 + + class D1[type Elem, type Value](x: Elem) extends C[Elem, Value](x) + class DD extends D1[Int, Int](2) + val arg3: CC & DD = ??? + val res3 = f(arg3) + val chk3: (C1 & D1) { type Elem = String; type Value = String } = res3 + val arg4: CC | DD = ??? + val res4 = f(arg4) + val chk4: C[String, String] = ??? + + class CX[type Elem](x: Elem) extends C1[Elem, Int](x) + class DX[type Value]() extends D1[Int, Value](2) + val arg5: CX[Int] & DX[Int] = ??? + val res5 = f(arg5) + val chk5: (C1 & D1) { type Elem = String; type Value = String } = res5 + val chk6: C1[String, String] & D1[String, String] = chk5 + val chk7: (C1 & D1) { type Elem = String; type Value = String } = chk6 } -// Adapated from i94-nada +// Adapted from i94-nada, somewhat non-sensical trait Test1 { trait Monad[type Elem] { def unit: Elem @@ -40,7 +70,21 @@ trait Test1 { case class Left[A,B](unit: A) extends Either[A,B] with Monad[A] case class Right[A,B](unit: B) extends Either[A,B] with Monad[B] def flatMap[X,Y,M <: Monad](m: M[Elem = X], f: X => M[Elem = Y]): M[Elem = Y] = f(m.unit) - println(flatMap(Left(1), {x: Int => Left(x)})) + val res = flatMap(Left(1), {x: Int => Left(x)}) + val chk: Either[Int, Nothing] & Monad & Product1[Int] = res +} + +// Adapted from i94-nada, this time with more sense +trait Test2 { + trait Monad[type Elem] { + def unit: Elem + } + sealed abstract class Either[A,B] + case class Left[type Elem, B](unit: Elem) extends Either[Elem,B] with Monad[Elem] + case class Right[A, type Elem](unit: Elem) extends Either[A,Elem] with Monad[Elem] + def flatMap[X,Y,M <: Monad](m: M[Elem = X], f: X => M[Elem = Y]): M[Elem = Y] = f(m.unit) + val res = flatMap(Left(1), {x: Int => Left(x)}) + val chk: Left[Int, Nothing] = res } |