diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/neg/customArgs/typers.scala | 2 | ||||
-rw-r--r-- | tests/neg/i1050c.scala | 3 | ||||
-rw-r--r-- | tests/neg/i2033.scala | 21 | ||||
-rw-r--r-- | tests/run/hmap.scala | 97 |
4 files changed, 121 insertions, 2 deletions
diff --git a/tests/neg/customArgs/typers.scala b/tests/neg/customArgs/typers.scala index 49742ebbd..9432ab039 100644 --- a/tests/neg/customArgs/typers.scala +++ b/tests/neg/customArgs/typers.scala @@ -30,7 +30,7 @@ object typers { } type L[X] = scala.collection.immutable.List[X] - type M[X, Y] <: scala.collection.immutable.Map[X, Y] // error: only classes can have declared but undefined members + type M[X, Y] <: scala.collection.immutable.Map[X, Y] // old-error: only classes can have declared but undefined members object hk { def f(x: L) // error: missing type parameter diff --git a/tests/neg/i1050c.scala b/tests/neg/i1050c.scala index 19570eb83..ecfaa3ea3 100644 --- a/tests/neg/i1050c.scala +++ b/tests/neg/i1050c.scala @@ -27,7 +27,8 @@ object Tiark4 { v.brand("boom!") } object V { // error: cannot be instantiated - type Y >: Any <: Nothing // error: only classes can have declared but undefined members + type Y >: Any <: Nothing // old-error: only classes can have declared but undefined members + type Z } object Tiark5 { trait A { type L <: Nothing } 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/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") + } +} |