aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/neg/i2001.scala6
-rw-r--r--tests/neg/i2033.scala21
-rw-r--r--tests/pos/inferOverloaded.scala41
-rw-r--r--tests/run/hmap.scala97
-rw-r--r--tests/run/lazy-implicit-lists.check4
-rw-r--r--tests/run/lazy-implicit-lists.scala87
-rw-r--r--tests/run/lazy-implicit-nums.check1
-rw-r--r--tests/run/lazy-implicit-nums.scala58
8 files changed, 315 insertions, 0 deletions
diff --git a/tests/neg/i2001.scala b/tests/neg/i2001.scala
new file mode 100644
index 000000000..82518890c
--- /dev/null
+++ b/tests/neg/i2001.scala
@@ -0,0 +1,6 @@
+class A {
+ def odd(x: Int) = if (x == 0) false else !even(x-1)
+ def even(x: Int) = if (x == 0) true else !odd(x-1) // error: overloaded or recursive method needs result type
+
+ lazy val x = x // error: recursive value needs type
+}
diff --git a/tests/neg/i2033.scala b/tests/neg/i2033.scala
new file mode 100644
index 000000000..b28a0d99e
--- /dev/null
+++ b/tests/neg/i2033.scala
@@ -0,0 +1,21 @@
+import java.io._
+import collection._
+object Test {
+ def check(obj: AnyRef): Unit = {
+ val bos = new ByteArrayOutputStream()
+ val out = new ObjectOutputStream(println) // error
+ val arr = bos toByteArray ()
+ val in = (())
+ val deser = ()
+ val lhs = mutable LinkedHashSet ()
+ check(lhs)
+ }
+}
+
+// minimization
+object Test2 {
+ class ObjectOutputStream(out: String) {
+ def this() = this("")
+ }
+ val out = new ObjectOutputStream(println) // error
+}
diff --git a/tests/pos/inferOverloaded.scala b/tests/pos/inferOverloaded.scala
new file mode 100644
index 000000000..e7179a04a
--- /dev/null
+++ b/tests/pos/inferOverloaded.scala
@@ -0,0 +1,41 @@
+class MySeq[T] {
+ def map1[U](f: T => U): MySeq[U] = new MySeq[U]
+ def map2[U](f: T => U): MySeq[U] = new MySeq[U]
+}
+
+class MyMap[A, B] extends MySeq[(A, B)] {
+ def map1[C](f: (A, B) => C): MySeq[C] = new MySeq[C]
+ def map1[C, D](f: (A, B) => (C, D)): MyMap[C, D] = new MyMap[C, D]
+ def map1[C, D](f: ((A, B)) => (C, D)): MyMap[C, D] = new MyMap[C, D]
+
+ def foo(f: Function2[Int, Int, Int]): Unit = ()
+ def foo[R](pf: PartialFunction[(A, B), R]): MySeq[R] = new MySeq[R]
+}
+
+object Test {
+ val m = new MyMap[Int, String]
+
+ // This one already worked because it is not overloaded:
+ m.map2 { case (k, v) => k - 1 }
+
+ // These already worked because preSelectOverloaded eliminated the non-applicable overload:
+ m.map1(t => t._1)
+ m.map1((kInFunction, vInFunction) => kInFunction - 1)
+ val r1 = m.map1(t => (t._1, 42.0))
+ val r1t: MyMap[Int, Double] = r1
+
+ // These worked because the argument types are known for overload resolution:
+ m.map1({ case (k, v) => k - 1 }: PartialFunction[(Int, String), Int])
+ m.map2({ case (k, v) => k - 1 }: PartialFunction[(Int, String), Int])
+
+ // These ones did not work before:
+ m.map1 { case (k, v) => k }
+ val r = m.map1 { case (k, v) => (k, k*10) }
+ val rt: MyMap[Int, Int] = r
+ m.foo { case (k, v) => k - 1 }
+
+ // Used to be ambiguous but overload resolution now favors PartialFunction
+ def h[R](pf: Function2[Int, String, R]): Unit = ()
+ def h[R](pf: PartialFunction[(Double, Double), R]): Unit = ()
+ h { case (a: Double, b: Double) => 42: Int }
+}
diff --git a/tests/run/hmap.scala b/tests/run/hmap.scala
new file mode 100644
index 000000000..d84419ce1
--- /dev/null
+++ b/tests/run/hmap.scala
@@ -0,0 +1,97 @@
+trait Tuple
+case class TCons[H, T <: Tuple](h: H, t: T) extends Tuple
+final case object TNil extends Tuple
+
+// Type level natural numbers -------------------------------------------------
+
+sealed trait Nat
+sealed trait Succ[P <: Nat] extends Nat
+sealed trait Zero extends Nat
+
+// Accessor type class to compute the N'th element of an Tuple L --------------
+
+trait At[L <: Tuple, N <: Nat, Out] {
+ def apply(l: L): Out
+}
+
+object At {
+ implicit def caseZero[H, T <: Tuple]: At[H TCons T, Zero, H] =
+ new At[H TCons T, Zero, H] {
+ def apply(l: H TCons T): H = {
+ val (h TCons _) = l
+ h
+ }
+ }
+
+ implicit def caseN[H, T <: Tuple, N <: Nat, O]
+ (implicit a: At[T, N, O]): At[H TCons T, Succ[N], O] =
+ new At[H TCons T, Succ[N], O] {
+ def apply(l: H TCons T): O = {
+ val (_ TCons t) = l
+ a(t)
+ }
+ }
+}
+
+// An HMap is an Tuple with HEntry elements. We are reusing Tuple for it's nice syntax
+
+final case class HEntry[K, V](value: V)
+
+// Accessor type class to compute the element of type K in a HMap L -----------
+
+trait PhantomGet[K, M <: Tuple, I <: Nat] // extends PhantomAny
+
+object PhantomGet {
+ implicit def getHead[K, V, T <: Tuple]
+ : PhantomGet[K, HEntry[K, V] TCons T, Zero] = null
+
+ implicit def getTail[K, H, T <: Tuple, I <: Nat]
+ (implicit t: PhantomGet[K, T, I])
+ : PhantomGet[K, H TCons T, Succ[I]] = null
+}
+
+// Syntax ---------------------------------------------------------------------
+
+object syntax {
+ object hmap {
+ implicit class HmapGet[M <: Tuple](m: M) {
+ def get[K, V, I <: Nat](k: K)
+ (implicit
+ g: PhantomGet[k.type, M, I],
+ a: At[M, I, HEntry[k.type, V]]
+ ): V = a(m).value
+ }
+
+ def --[K, V](key: K, value: V) = HEntry[key.type, V](value)
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ import syntax.hmap._
+
+ val map1 =
+ TCons(HEntry[K = "name"]("foo"),
+ TCons(HEntry[K = "genre"](true),
+ TCons(HEntry[K = "moneyz"](123),
+ TCons(HEntry[K = "cat"]("bar"),
+ (TNil: TNil.type)))))
+
+ assert(map1.get("name") == "foo")
+ assert(map1.get("genre") == true)
+ assert(map1.get("moneyz") == 123)
+ assert(map1.get("cat") == "bar")
+
+ val map2 =
+ TCons(--("name" , "foo"),
+ TCons(--("genre" , true),
+ TCons(--("moneyz", 123),
+ TCons(--("cat" , "bar"),
+ TNil))))
+
+ assert(map2.get("name") == "foo")
+ assert(map2.get("genre") == true)
+ assert(map2.get("moneyz") == 123)
+ assert(map2.get("cat") == "bar")
+ }
+}
diff --git a/tests/run/lazy-implicit-lists.check b/tests/run/lazy-implicit-lists.check
new file mode 100644
index 000000000..60e3225b1
--- /dev/null
+++ b/tests/run/lazy-implicit-lists.check
@@ -0,0 +1,4 @@
+List()
+List(1, 2, 3)
+List()
+List(1, 2, 3)
diff --git a/tests/run/lazy-implicit-lists.scala b/tests/run/lazy-implicit-lists.scala
new file mode 100644
index 000000000..72099d0b2
--- /dev/null
+++ b/tests/run/lazy-implicit-lists.scala
@@ -0,0 +1,87 @@
+trait L
+case class C(hd: Int, tl: L) extends L
+case object N extends L
+
+trait Sum[+S1, +S2]
+case class Fst[+F](x: F) extends Sum[F, Nothing]
+case class Snd[+S](x: S) extends Sum[Nothing, S]
+
+case class Prod[+P1, +P2](fst: P1, snd: P2)
+
+trait shaped[SH1, SH2] {
+ def toShape(x: SH1): SH2
+ def fromShape(x: SH2): SH1
+}
+
+object Test {
+
+ type LShape = Sum[Prod[Int, L], Unit]
+
+ implicit def LShape: L `shaped` LShape =
+ new (L `shaped` LShape) {
+ def toShape(xs: L) = xs match {
+ case C(x, xs1) => Fst(Prod(x, xs1))
+ case N => Snd(())
+ }
+ def fromShape(sh: LShape) = sh match {
+ case Fst(Prod(x, xs1)) => C(x, xs1)
+ case Snd(()) => N
+ }
+ }
+
+ trait Listable[T] {
+ def toList(x: T): List[Int]
+ }
+
+ implicit def ShapedListable[T, U](implicit
+ ev1: T shaped U,
+ ev2: Listable[U]
+ ): Listable[T] =
+ new Listable[T] {
+ def toList(x: T) = ev2.toList(ev1.toShape(x))
+ }
+
+ implicit def SumListable[T, U](implicit
+ ev1: => Listable[T],
+ ev2: => Listable[U]
+ ): Listable[Sum[T, U]] =
+ new Listable[Sum[T, U]] {
+ def toList(s: Sum[T, U]) = s match {
+ case Fst(x) => ev1.toList(x)
+ case Snd(x) => ev2.toList(x)
+ }
+ }
+
+ implicit def ProdListable[T, U](implicit
+ ev1: Listable[T],
+ ev2: Listable[U]
+ ): Listable[Prod[T, U]] =
+ new Listable[Prod[T, U]] {
+ def toList(p: Prod[T, U]) = ev1.toList(p.fst) ++ ev2.toList(p.snd)
+ }
+
+ implicit def IntListable: Listable[Int] =
+ new Listable[Int] {
+ def toList(n: Int) = n :: Nil
+ }
+
+
+ implicit def UnitListable: Listable[Unit] =
+ new Listable[Unit] {
+ def toList(u: Unit) = Nil
+ }
+
+ def toList[T, U >: T](x: T)(implicit ev1: Listable[U]) = ev1.toList(x)
+
+ def main(args: Array[String]) = {
+ locally { // with specialized Listable
+ implicit lazy val LListable: Listable[L] = ShapedListable
+ println(toList(N))
+ println(toList(C(1, C(2, C(3, N)))))
+ }
+ locally { // without specialized Listable
+ println(toList(N))
+ println(toList(C(1, C(2, C(3, N)))))
+ }
+ }
+}
diff --git a/tests/run/lazy-implicit-nums.check b/tests/run/lazy-implicit-nums.check
new file mode 100644
index 000000000..00750edc0
--- /dev/null
+++ b/tests/run/lazy-implicit-nums.check
@@ -0,0 +1 @@
+3
diff --git a/tests/run/lazy-implicit-nums.scala b/tests/run/lazy-implicit-nums.scala
new file mode 100644
index 000000000..967472735
--- /dev/null
+++ b/tests/run/lazy-implicit-nums.scala
@@ -0,0 +1,58 @@
+trait Nat
+case class S(x: Nat) extends Nat
+case class Z() extends Nat
+
+trait Sum[+S1, +S2]
+case class Fst[+F](x: F) extends Sum[F, Nothing]
+case class Snd[+S](x: S) extends Sum[Nothing, S]
+
+trait shaped[SH1, SH2] {
+ def toShape(x: SH1): SH2
+ def fromShape(x: SH2): SH1
+}
+
+object Test {
+
+ type NatShape = Sum[Nat, Z]
+
+ implicit def natShape: Nat `shaped` NatShape =
+ new (Nat `shaped` NatShape) {
+ def toShape(n: Nat) = n match {
+ case S(m) => Fst(m)
+ case Z() => Snd(Z())
+ }
+ def fromShape(s: NatShape) = s match {
+ case Fst(n) => S(n)
+ case Snd(_) => Z()
+ }
+ }
+
+ trait Countable[T] {
+ def count(x: T): Int
+ }
+
+ implicit def ShapedCountable[T, U](implicit
+ ev1: T shaped U,
+ ev2: Countable[U]
+ ): Countable[T] =
+ new Countable[T] {
+ def count(x: T) = ev2.count(ev1.toShape(x))
+ }
+
+ implicit def SumCountable[T, U](implicit
+ ev1: => Countable[T]
+ ): Countable[Sum[T, U]] =
+ new Countable[Sum[T, U]] {
+ def count(s: Sum[T, U]) = s match {
+ case Fst(x) => ev1.count(x) + 1
+ case Snd(_) => 0
+ }
+ }
+
+ def count[T, U >: T](x: T)(implicit ev1: Countable[U]) = ev1.count(x)
+
+ def main(args: Array[String]) = {
+ println(
+ count(S(S(S(Z())))))
+ }
+}