summaryrefslogtreecommitdiff
path: root/test/files/run/t8017/value-class-lambda.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-12-13 10:37:44 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-12-15 22:18:10 +0100
commit6a4947c45c0b5fac3297da320b9627069a7b5ac4 (patch)
tree28f6e71a1dbf9043a5fd4bb69f87f2f383c618da /test/files/run/t8017/value-class-lambda.scala
parentfcf1adad75553d25ea4e6afe37c971902b11f35e (diff)
downloadscala-6a4947c45c0b5fac3297da320b9627069a7b5ac4.tar.gz
scala-6a4947c45c0b5fac3297da320b9627069a7b5ac4.tar.bz2
scala-6a4947c45c0b5fac3297da320b9627069a7b5ac4.zip
SI-8017 Value class awareness for -Ydelamdafy:method
The delambdafy creates a bridge method which requires adaptation of the result type to the generic `Object`, which is the erased return type of FunctionN. This bridge building reused some code from erasure, now refactored into TypeAdaptingTransformer. But, it was running into problems with: class C(a: Int) extends AnyVal (x: Any) => new C(0) It created (forgive the pseudo quasiquote syntax): class anonfun$ extends Function1[Any, C] { def apply#1(a: Object): Int = 0 <bridge> def apply#2(a: Object): Object = { val result: Int = apply#1(a) ${adapt(Ident("result"), ObjectType)} } } This resulted in primitive boxing, rather than value class boxing. Instead, we need the call to the main apply method to be typed as `ErasedValueClass(C, Int)`, which `adapt` takes as a trigger to perform value class boxing. Finally, we have to run the post-erasure transformer over the adapted tree to eliminate remnants of `ErasedValueClass` from the types of trees.
Diffstat (limited to 'test/files/run/t8017/value-class-lambda.scala')
-rw-r--r--test/files/run/t8017/value-class-lambda.scala40
1 files changed, 40 insertions, 0 deletions
diff --git a/test/files/run/t8017/value-class-lambda.scala b/test/files/run/t8017/value-class-lambda.scala
new file mode 100644
index 0000000000..370023b194
--- /dev/null
+++ b/test/files/run/t8017/value-class-lambda.scala
@@ -0,0 +1,40 @@
+object Test {
+ def testC {
+ val f1 = (c: C) => c.value
+ val f2 = (x: Int) => new C(x)
+ val f3 = (c1: C) => (c2: C) => (c1, c2)
+ val r1 = f2(2)
+ val r2 = f2(2)
+ val r3 = f3(r1)(r2)
+ val result = f1(r3._2)
+ assert(result == 2)
+ }
+
+ def testD {
+ val f1 = (c: D) => c.value
+ val f2 = (x: String) => new D(x)
+ val f3 = (c1: D) => (c2: D) => (c1, c2)
+ val r1 = f2("2")
+ val r2 = f2("2")
+ val r3 = f3(r1)(r2)
+ val result = f1(r3._2)
+ assert(result == "2")
+ }
+
+ def testE {
+ val f1 = (c: E[Int]) => c.value
+ val f2 = (x: Int) => new E(x)
+ val f3 = (c1: E[Int]) => (c2: E[Int]) => (c1, c2)
+ val r1 = f2(2)
+ val r2 = f2(2)
+ val r3 = f3(r1)(r2)
+ val result = f1(r3._2)
+ assert(result == 2)
+ }
+
+ def main(args: Array[String]) {
+ testC
+ testD
+ testE
+ }
+}