summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/SpecializeTypes.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/SpecializeTypes.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/SpecializeTypes.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 998f0b22cb..0050d08f1b 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -285,6 +285,19 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
for ((tvar, tpe) <- sym.info.typeParams.zip(args) if !tvar.isSpecialized || !isPrimitiveValueType(tpe))
yield tpe
+ /** Is `member` potentially affected by specialization? This is a gross overapproximation,
+ * but it should be okay for use outside of specialization.
+ */
+ def possiblySpecialized(sym: Symbol) = specializedTypeVars(sym).nonEmpty
+
+ /** Refines possiblySpecialized taking into account the instantiation of the specialized type variables at `site` */
+ def isSpecializedIn(sym: Symbol, site: Type) =
+ specializedTypeVars(sym) exists { tvar =>
+ val concretes = concreteTypes(tvar)
+ (concretes contains AnyRefClass) || (concretes contains site.memberType(tvar))
+ }
+
+
val specializedType = new TypeMap {
override def apply(tp: Type): Type = tp match {
case TypeRef(pre, sym, args) if args.nonEmpty =>