summaryrefslogtreecommitdiff
path: root/test/files/run
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-03-21 08:47:45 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2016-03-26 22:54:12 -0700
commit2aa8eba5007f0e0eda3a2ef3fdffa1f468dc1fa4 (patch)
treea552aa90cac3d45cbcff3827407c5b3549f81298 /test/files/run
parentf922f367d58b3ba6bbb4cb0864ce82c5cd6f7966 (diff)
downloadscala-2aa8eba5007f0e0eda3a2ef3fdffa1f468dc1fa4.tar.gz
scala-2aa8eba5007f0e0eda3a2ef3fdffa1f468dc1fa4.tar.bz2
scala-2aa8eba5007f0e0eda3a2ef3fdffa1f468dc1fa4.zip
Test bytecode emitted for indy sammy
Test that SAM conversion happens after implicit view application A function node is first type checked, and parameter types are inferred, regardless of whether the expected function type is one of our built-in FunctionN classes, or a user-defined Single Abstract Method type. `typedFunction` always assigns a built-in `FunctionN` type to the tree, though. Next, if the expected type is a (polymorphic) SAM type, this creates a tension between the tree's type and the expect type. This gap is closed by the adapt method, by applying one of the implicit conversion in the spec in order (e.g., numeric widening, implicit view application, and now, also SAM conversion) Thus, `adaptToSam` will assign the expected SAM type to the `Function` tree. (This may require some type inference.) The back-end will emit the right invokedynamic instruction that uses Java's LambdaMetaFactory to spin up a class that implements the target method (whether it's defined in FunctionN or some other Java functional interface).
Diffstat (limited to 'test/files/run')
-rw-r--r--test/files/run/sammy_after_implicit_view.scala28
1 files changed, 28 insertions, 0 deletions
diff --git a/test/files/run/sammy_after_implicit_view.scala b/test/files/run/sammy_after_implicit_view.scala
new file mode 100644
index 0000000000..30e3babc75
--- /dev/null
+++ b/test/files/run/sammy_after_implicit_view.scala
@@ -0,0 +1,28 @@
+trait MySam { def apply(x: Int): String }
+
+// check that SAM conversion happens after implicit view application
+object Test extends App {
+ final val AnonFunClass = "$anon$"
+ final val LMFClass = "$$Lambda$" // LambdaMetaFactory names classes like this
+
+ // if there's an implicit conversion, it takes precedence
+ def statusQuo() = {
+ import language.implicitConversions
+ var ok = false
+ implicit def fun2sam(fun: Int => String): MySam = { ok = true; new MySam { def apply(x: Int) = fun(x) } }
+ val className = (((x: Int) => x.toString): MySam).getClass.toString
+ assert(ok, "implicit conversion not called")
+ assert(className contains AnonFunClass, className)
+ assert(!(className contains LMFClass), className)
+ }
+
+ // indirectly check that this sam type instance was created from a class spun up by LambdaMetaFactory
+ def statusIndy() = {
+ val className = (((x: Int) => x.toString): MySam).getClass.toString
+ assert(!(className contains AnonFunClass), className)
+ assert(className contains LMFClass, className)
+ }
+
+ statusQuo()
+ statusIndy()
+} \ No newline at end of file