summaryrefslogtreecommitdiff
path: root/test/files/run/sammy_restrictions_LMF.scala
diff options
context:
space:
mode:
Diffstat (limited to 'test/files/run/sammy_restrictions_LMF.scala')
-rw-r--r--test/files/run/sammy_restrictions_LMF.scala57
1 files changed, 57 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..aa49e14113
--- /dev/null
+++ b/test/files/run/sammy_restrictions_LMF.scala
@@ -0,0 +1,57 @@
+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 }
+
+trait TImpure { def apply(x: Int): String ; println(1) }
+
+trait Println { println(1) }
+trait TImpureSuper extends Println { def apply(x: Int): String }
+
+class C
+trait A extends C
+trait B extends A
+trait TClassParent extends B { 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)
+
+ notLMF((x => "a"): TImpure)
+ notLMF((x => "a"): TImpureSuper)
+
+ val fClassParent: TClassParent = x => "a"
+ notLMF(fClassParent)
+ assert(fClassParent(1) == "a")
+}