aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-01-05 16:02:09 +0700
committerMartin Odersky <odersky@gmail.com>2017-01-05 18:00:06 +0700
commitaa6ebe938639f07dd6f5612e645f1449f37a86eb (patch)
tree24d257c1f12d0f5cb9b76102043046e3a904d98a /tests
parent42eb864dc752254fc3b8b0428570fe94aa1dafc7 (diff)
downloaddotty-aa6ebe938639f07dd6f5612e645f1449f37a86eb.tar.gz
dotty-aa6ebe938639f07dd6f5612e645f1449f37a86eb.tar.bz2
dotty-aa6ebe938639f07dd6f5612e645f1449f37a86eb.zip
Implement structural type member access
New scheme for implementing structural type member access.
Diffstat (limited to 'tests')
-rw-r--r--tests/neg/zoo.scala14
-rw-r--r--tests/pos/zoo2.scala44
-rw-r--r--tests/run/structural.scala33
-rw-r--r--tests/run/structuralNoSuchMethod.check1
-rw-r--r--tests/run/structuralNoSuchMethod.scala23
5 files changed, 108 insertions, 7 deletions
diff --git a/tests/neg/zoo.scala b/tests/neg/zoo.scala
index 19efcc1d7..1674548e8 100644
--- a/tests/neg/zoo.scala
+++ b/tests/neg/zoo.scala
@@ -7,19 +7,19 @@ type Grass = {
}
type Animal = {
type Food
- def eats(food: Food): Unit // error
- def gets: Food // error
+ def eats(food: Food): Unit
+ def gets: Food
}
type Cow = {
type IsMeat = Any
type Food <: Grass
- def eats(food: Grass): Unit // error
- def gets: Grass // error
+ def eats(food: Grass): Unit
+ def gets: Grass
}
type Lion = {
type Food = Meat
- def eats(food: Meat): Unit // error
- def gets: Meat // error
+ def eats(food: Meat): Unit
+ def gets: Meat
}
def newMeat: Meat = new {
type IsMeat = Any
@@ -40,5 +40,5 @@ def newLion: Lion = new {
}
val milka = newCow
val leo = newLion
-leo.eats(milka) // structural select not supported
+leo.eats(milka) // error: no projector found
}
diff --git a/tests/pos/zoo2.scala b/tests/pos/zoo2.scala
new file mode 100644
index 000000000..9911416d3
--- /dev/null
+++ b/tests/pos/zoo2.scala
@@ -0,0 +1,44 @@
+object Test {
+type Meat = {
+ type IsMeat = Any
+}
+type Grass = {
+ type IsGrass = Any
+}
+type Animal = {
+ type Food
+ def eats(food: Food): Unit
+ def gets: Food
+}
+type Cow = {
+ type IsMeat = Any
+ type Food <: Grass
+ def eats(food: Grass): Unit
+ def gets: Grass
+}
+type Lion = {
+ type Food = Meat
+ def eats(food: Meat): Unit
+ def gets: Meat
+}
+def newMeat: Meat = new {
+ type IsMeat = Any
+}
+def newGrass: Grass = new {
+ type IsGrass = Any
+}
+def newCow: Cow = new {
+ type IsMeat = Any
+ type Food = Grass
+ def eats(food: Grass) = ()
+ def gets = newGrass
+}
+def newLion: Lion = new {
+ type Food = Meat
+ def eats(food: Meat) = ()
+ def gets = newMeat
+}
+val milka = newCow
+val leo = newLion
+leo.eats(milka)
+}
diff --git a/tests/run/structural.scala b/tests/run/structural.scala
new file mode 100644
index 000000000..43f008b5f
--- /dev/null
+++ b/tests/run/structural.scala
@@ -0,0 +1,33 @@
+case class Record(elems: (String, Any)*)
+
+object Record {
+
+ implicit def projector: Projector[Record] = new Projector[Record] {
+ def get(receiver: Record, name: String): Any =
+ receiver.elems.find(_._1 == name).get._2
+ }
+
+}
+
+object Test {
+ import scala.reflect.Projector.reflectiveProjector
+ import Record.projector
+
+ def f(closeable: { def close(): Unit }) =
+ closeable.close()
+
+ type RN = Record { val name: String }
+
+ def g(r: RN) = r.name
+
+ val rr: RN = Record("name" -> "Bob", "age" -> 42).asInstanceOf[RN]
+
+ def main(args: Array[String]): Unit = {
+ f(new java.io.PrintStream("foo"))
+ assert(g(rr) == "Bob")
+
+ val s: { def concat(s: String): String } = "abc"
+ assert(s.concat("def") == "abcdef")
+ }
+}
+
diff --git a/tests/run/structuralNoSuchMethod.check b/tests/run/structuralNoSuchMethod.check
new file mode 100644
index 000000000..20576fc9c
--- /dev/null
+++ b/tests/run/structuralNoSuchMethod.check
@@ -0,0 +1 @@
+no such method
diff --git a/tests/run/structuralNoSuchMethod.scala b/tests/run/structuralNoSuchMethod.scala
new file mode 100644
index 000000000..3d33c9d8b
--- /dev/null
+++ b/tests/run/structuralNoSuchMethod.scala
@@ -0,0 +1,23 @@
+import scala.reflect.Projector.reflectiveProjector
+
+/** Demonstrates limitation of structural method dispatch (in Scala 2.x and dotty).
+ * The method must be defined at exactly the argument types given in the structural type;
+ * Generic instantiation is not possible.
+ */
+object Test {
+ type T = { def f(x: String, y: String): String }
+
+ class C[X] {
+ def f(x: X, y: String): String = "f1"
+ }
+
+ val x: T = new C[String]
+
+ def main(args: Array[String]) =
+ try println(x.f("", "")) // throws NoSuchMethodException
+ catch {
+ case ex: NoSuchMethodException =>
+ println("no such method")
+ }
+
+}