summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/files/run/sammy_specialization_restriction.scala34
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala24
2 files changed, 58 insertions, 0 deletions
diff --git a/test/files/run/sammy_specialization_restriction.scala b/test/files/run/sammy_specialization_restriction.scala
new file mode 100644
index 0000000000..4487bb3ad7
--- /dev/null
+++ b/test/files/run/sammy_specialization_restriction.scala
@@ -0,0 +1,34 @@
+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()
+}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala b/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala
index f7218c576c..b9e45a7dc9 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala
@@ -71,6 +71,23 @@ class IndySammyTest extends ClearAfterClass {
)
}
+// def testSpecial(lam: String, lamTp: String, arg: String)(allowMessage: StoreReporter#Info => Boolean = _ => false) = {
+// val cls = compile("trait Special[@specialized A] { def apply(a: A): A}" )
+// val methodNodes = compileMethods(compiler)(s"def lam : $lamTp = $lam" +";"+ appDef(arg), allowMessage)
+//
+// val anonfun = methodNodes.filter(_.name contains "$anonfun$").map(convertMethod)
+// val lamInsn = methodNodes.find(_.name == "lam").map(instructionsFromMethod).get.dropNonOp
+// val applyInvoke = methodNodes.find(_.name == "app").map(convertMethod).get
+//
+// assert(lamInsn.length == 2 && lamInsn.head.isInstanceOf[InvokeDynamic], lamInsn)
+// assertSameCode(anonfun, lamBody)
+// assertSameCode(applyInvoke, List(
+// VarOp(ALOAD, 0),
+// Invoke(INVOKEVIRTUAL, "C", "lam", s"()L${funClassName(from, to)};", false)) ++ appArgs ++ List(
+// Invoke(INVOKEINTERFACE, funClassName(from, to), "apply", applySig, true), ret)
+// )
+// }
+
// x => x : VC => VC applied to VC(1)
@Test
def testVC_VC_VC =
@@ -127,6 +144,13 @@ class IndySammyTest extends ClearAfterClass {
List(Op(ICONST_1), Invoke(INVOKESTATIC, "scala/runtime/BoxesRunTime", "boxToInteger", "(I)Ljava/lang/Integer;", false)),
Op(IRETURN))()
+ // TODO
+ // x => x : Special[Int] applied to 1
+// @Test
+// def testSpecial_Int_1 =
+// testSpecial("x => x", "Special[Int]", "1")()
+
+
// Tests ThisReferringMethodsTraverser
@Test
def testStaticIfNoThisReference: Unit = {