diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-01-29 09:15:36 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-01-31 16:50:13 +0100 |
commit | d0afd7ece04e1974093c8c37b0ff6654742ab57b (patch) | |
tree | db2f4f0e30eae93cf1c9721ffb351634020829e4 /src | |
parent | a5b0fc49e517d1c63d22f9909ac9bed0552ed466 (diff) | |
download | scala-d0afd7ece04e1974093c8c37b0ff6654742ab57b.tar.gz scala-d0afd7ece04e1974093c8c37b0ff6654742ab57b.tar.bz2 scala-d0afd7ece04e1974093c8c37b0ff6654742ab57b.zip |
SI-7700 @unspecialized, Part Deux: Now Working.
This annotation was introduced to allow us to mark methods within
a specialized trait as immune from specialization. In particular,
this is desirable for `Function1.{andThen, compose}`.
However, it seems we need to check for this in two places in the
specialization code base. The feature is now backed with a test.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index c505d9dc5f..9e86e052c0 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -306,6 +306,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { /** Return the specialized name of 'sym' in the given environment. It * guarantees the same result regardless of the map order by sorting * type variables alphabetically. + * + * !!! Is this safe in the face of the following? + * scala> trait T { def foo[A] = 0}; object O extends T { override def foo[B] = 0 } */ private def specializedName(sym: Symbol, env: TypeEnv): TermName = { val tvars = ( @@ -391,13 +394,16 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * enclosing member with the annotation. */ private def needsSpecialization(env: TypeEnv, sym: Symbol): Boolean = ( - !sym.ownerChain.exists(_ hasAnnotation UnspecializedClass) && ( + !hasUnspecializableAnnotation(sym) && ( specializedTypeVars(sym).intersect(env.keySet).diff(wasSpecializedForTypeVars(sym)).nonEmpty || sym.isClassConstructor && (sym.enclClass.typeParams exists (_.isSpecialized)) || isNormalizedMember(sym) && info(sym).typeBoundsIn(env) ) ) + private def hasUnspecializableAnnotation(sym: Symbol): Boolean = + sym.ownerChain.exists(_ hasAnnotation UnspecializedClass) + def isNormalizedMember(m: Symbol) = m.isSpecialized && (info get m exists { case NormalizedMember(_) => true case _ => false @@ -907,16 +913,20 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } if (sym.isMethod) { - val stvars = specializedTypeVars(sym) - if (stvars.nonEmpty) - debuglog("specialized %s on %s".format(sym.fullLocationString, stvars.map(_.name).mkString(", "))) + if (hasUnspecializableAnnotation(sym)) { + List() + } else { + val stvars = specializedTypeVars(sym) + if (stvars.nonEmpty) + debuglog("specialized %s on %s".format(sym.fullLocationString, stvars.map(_.name).mkString(", "))) - val tps1 = if (sym.isConstructor) tps filter (sym.info.paramTypes contains _) else tps - val tps2 = tps1 filter stvars - if (!sym.isDeferred) - addConcreteSpecMethod(sym) + val tps1 = if (sym.isConstructor) tps filter (sym.info.paramTypes contains _) else tps + val tps2 = tps1 filter stvars + if (!sym.isDeferred) + addConcreteSpecMethod(sym) - specializeOn(tps2) + specializeOn(tps2) + } } else Nil } |