diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-03-29 00:21:07 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-03-29 12:34:19 -0700 |
commit | 0a3362b3ea5cd7355cd9ccc529783549a4cb5c5f (patch) | |
tree | cd1c7a3892bfbd657870c619440c047334a1373f /test | |
parent | 3ae39036771acb107cbb4a37fe6113c243d89acc (diff) | |
download | scala-0a3362b3ea5cd7355cd9ccc529783549a4cb5c5f.tar.gz scala-0a3362b3ea5cd7355cd9ccc529783549a4cb5c5f.tar.bz2 scala-0a3362b3ea5cd7355cd9ccc529783549a4cb5c5f.zip |
Specialization precludes use of LambdaMetaFactory for SAM
When a SAM type is specialized (i.e., a specialized type
parameter receives a specialized type argument), do not use
LambdaMetaFactory (expand during Uncurry instead).
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.
Diffstat (limited to 'test')
-rw-r--r-- | test/files/run/sammy_specialization_restriction.scala | 34 | ||||
-rw-r--r-- | test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala | 24 |
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 = { |