summaryrefslogtreecommitdiff
path: root/test
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
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')
-rw-r--r--test/files/run/sammy_restrictions_LMF.scala42
-rw-r--r--test/files/run/sammy_specialization_restriction.scala34
2 files changed, 42 insertions, 34 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)
+
+
+}
diff --git a/test/files/run/sammy_specialization_restriction.scala b/test/files/run/sammy_specialization_restriction.scala
deleted file mode 100644
index 4487bb3ad7..0000000000
--- a/test/files/run/sammy_specialization_restriction.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-trait T[@specialized A] { def apply(a: A): A }
-trait TInt extends T[Int]
-
-// 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.
-object Test extends App {
- final val AnonFunClass = "$anonfun$"
- final val LMFClass = "$$Lambda$" // LambdaMetaFactory names classes like this
-
- def specializedSamPrecludesLMF() = {
- val className = ((x => x): T[Int]).getClass.toString
- assert((className contains AnonFunClass), className)
- assert(!(className contains LMFClass), className)
- }
-
- def specializedSamSubclassPrecludesLMF() = {
- val className = ((x => x): TInt).getClass.toString
- assert((className contains AnonFunClass), className)
- assert(!(className contains LMFClass), className)
- }
-
- def nonSpecializedSamUsesLMF() = {
- val className = ((x => x): T[String]).getClass.toString
- assert(!(className contains AnonFunClass), className)
- assert(className contains LMFClass, className)
- }
-
- specializedSamPrecludesLMF()
- nonSpecializedSamUsesLMF()
-}