summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/UnCurry.scala
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-03-29 00:21:07 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2016-03-29 12:34:19 -0700
commit0a3362b3ea5cd7355cd9ccc529783549a4cb5c5f (patch)
treecd1c7a3892bfbd657870c619440c047334a1373f /src/compiler/scala/tools/nsc/transform/UnCurry.scala
parent3ae39036771acb107cbb4a37fe6113c243d89acc (diff)
downloadscala-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 'src/compiler/scala/tools/nsc/transform/UnCurry.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index afa0fc92ff..9c4b125fc1 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -77,8 +77,8 @@ abstract class UnCurry extends InfoTransform
// We use Java's LambdaMetaFactory (LMF), which requires an interface for the sam's owner
private def mustExpandFunction(fun: Function) = forceExpandFunction || {
// (TODO: Can't use isInterface, yet, as it hasn't been updated for the new trait encoding)
- val canUseLambdaMetaFactory = inConstructorFlag == 0 && (fun.attachments.get[SAMFunction].map(_.samTp) match {
- case Some(userDefinedSamTp) =>
+ val canUseLambdaMetaFactory = inConstructorFlag == 0 && (fun.attachments.get[SAMFunction] match {
+ case Some(SAMFunction(userDefinedSamTp, sam)) =>
val tpSym = erasure.javaErasure(userDefinedSamTp).typeSymbol // we only care about what ends up in the bytecode
(
// LMF only supports interfaces
@@ -90,7 +90,9 @@ abstract class UnCurry extends InfoTransform
// to expand sam at compile time or use LMF, and this implementation restriction could be lifted.
&& tpSym.isStatic
// impl restriction -- we currently use the boxed apply, so not really useful to allow specialized sam types (https://github.com/scala/scala/pull/4971#issuecomment-198119167)
- && !tpSym.isSpecialized
+ // specialization and LMF are at odds, since LMF implements the single abstract method,
+ // but that's the one that specialization leaves generic, whereas we need to implement the specialized one to avoid boxing
+ && !specializeTypes.isSpecializedIn(sam, userDefinedSamTp)
)
case _ => true // our built-in FunctionN's are suitable for LambdaMetaFactory by construction