summaryrefslogtreecommitdiff
path: root/test/files/run/sammy_restrictions_LMF.scala
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-03-29 16:47:47 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2016-03-29 23:08:40 -0700
commit63f017586f31de11bc6004dca7cea0c26ceb5ff5 (patch)
treea1fd4c7e1a879aeb19981d8d71f7823d0c5bfad6 /test/files/run/sammy_restrictions_LMF.scala
parent0a3362b3ea5cd7355cd9ccc529783549a4cb5c5f (diff)
downloadscala-63f017586f31de11bc6004dca7cea0c26ceb5ff5.tar.gz
scala-63f017586f31de11bc6004dca7cea0c26ceb5ff5.tar.bz2
scala-63f017586f31de11bc6004dca7cea0c26ceb5ff5.zip
Better detection of types LMF cannot instantiate.
LambdaMetaFactory can only properly instantiate Java interfaces (with one abstract method, of course). A trait always compiles to an interface, but a subclass that can be instantiated may require mixing in further members, which LMF cannot do. (Nested traits, traits with fields,... do not qualify.) Traits that cannot be instantiated by LMF are still SAM targets, we simply created anonymous subclasses as before.
Diffstat (limited to 'test/files/run/sammy_restrictions_LMF.scala')
-rw-r--r--test/files/run/sammy_restrictions_LMF.scala42
1 files changed, 42 insertions, 0 deletions
diff --git a/test/files/run/sammy_restrictions_LMF.scala b/test/files/run/sammy_restrictions_LMF.scala
new file mode 100644
index 0000000000..40bb234a72
--- /dev/null
+++ b/test/files/run/sammy_restrictions_LMF.scala
@@ -0,0 +1,42 @@
+trait T[@specialized A] { def apply(a: A): A }
+trait TInt extends T[Int]
+
+trait TWithVal { val x: Any = 1; def apply(x: Int): String }
+
+object Test extends App {
+ final val AnonFunClass = "$anonfun$"
+ final val LMFClass = "$$Lambda$" // LambdaMetaFactory names classes like this
+
+ private def LMF(f: Any): Unit = {
+ val className = f.getClass.toString
+ assert(!(className contains AnonFunClass), className)
+ assert((className contains LMFClass), className)
+ }
+
+ private def notLMF(f: Any): Unit = {
+ val className = f.getClass.toString
+ assert((className contains AnonFunClass), className)
+ assert(!(className contains LMFClass), className)
+ }
+
+ // Check that we expand the SAM of a type that is specialized.
+ // This is an implementation restriction -- the current specialization scheme is not
+ // amenable to using LambdaMetaFactory to spin up subclasses.
+ // Since the generic method is abstract, and the specialized ones are concrete,
+ // specialization is rendered moot because we cannot implement the specialized method
+ // with the lambda using LMF.
+
+ // not LMF if specialized at this type
+ notLMF((x => x): T[Int])
+ // not LMF if specialized at this type (via subclass)
+ notLMF((x => x): TInt)
+ // LMF ok if not specialized at this type
+ LMF((x => x): T[String])
+
+ // traits with a val member also cannot be instantiated by LMF
+ val fVal: TWithVal = (x => "a")
+ notLMF(fVal)
+ assert(fVal.x == 1)
+
+
+}