summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
diff options
context:
space:
mode:
authorErik Osheim <d_m@plastic-idolatry.com>2012-02-19 10:25:03 -0500
committerErik Osheim <d_m@plastic-idolatry.com>2012-02-19 11:20:58 -0500
commitcf0ae72aae43dae1e47489fceb684e5448080736 (patch)
treebc087d70ea864ca8d6a91d6367dcf89c0eb77bb0 /src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
parent4a5c6a01840404edd362bd388e39f68cb6af5dc7 (diff)
downloadscala-cf0ae72aae43dae1e47489fceb684e5448080736.tar.gz
scala-cf0ae72aae43dae1e47489fceb684e5448080736.tar.bz2
scala-cf0ae72aae43dae1e47489fceb684e5448080736.zip
Fix [@spec A] to correctly induce AnyRef specialization.
While [@specialized A] already tries to include specialization, a bug in specializedOn prevented this from happening: any empty list could mean that the type var was unspecialized, or that it was specialized on everything. The fix is to have this function create the full list of symbols in the case where the @specialized annotation doesn't explicitly include any types.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala31
1 files changed, 15 insertions, 16 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 3254844344..fddb379a07 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -104,15 +104,17 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
private def specializedTypes(tps: List[Symbol]) = tps filter isSpecialized
private def specializedOn(sym: Symbol): List[Symbol] = {
sym getAnnotation SpecializedClass match {
- case Some(ann @ AnnotationInfo(_, args, _)) =>
+ case Some(AnnotationInfo(_, Nil, _)) => specializableTypes.map(_.typeSymbol)
+ case Some(ann @ AnnotationInfo(_, args, _)) => {
args map (_.tpe) flatMap { tp =>
tp baseType GroupOfSpecializable match {
case TypeRef(_, GroupOfSpecializable, arg :: Nil) =>
arg.typeArgs map (_.typeSymbol)
- case _ =>
+ case _ =>
List(tp.typeSymbol)
}
}
+ }
case _ => Nil
}
}
@@ -120,13 +122,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// If we replace `isBoundedGeneric` with (tp <:< AnyRefClass.tpe),
// then pos/spec-List.scala fails - why? Does this kind of check fail
// for similar reasons? Does `sym.isAbstractType` make a difference?
- private def isSpecializedAnyRefSubtype(tp: Type, sym: Symbol) = (
- // !!! Come back to this, not sure it's recognizing AnyRefModule
- (specializedOn(sym) exists (s => !isValueClass(s)))
- && !isValueClass(tp.typeSymbol)
- && isBoundedGeneric(tp)
- // && (tp <:< AnyRefClass.tpe)
- )
+ private def isSpecializedAnyRefSubtype(tp: Type, sym: Symbol) = {
+ specializedOn(sym).exists(s => !isValueClass(s)) &&
+ !isValueClass(tp.typeSymbol) &&
+ isBoundedGeneric(tp)
+ //(tp <:< AnyRefClass.tpe)
+ }
private def isBoundedGeneric(tp: Type) = tp match {
case TypeRef(_, sym, _) if sym.isAbstractType => (tp <:< AnyRefClass.tpe)
case TypeRef(_, sym, _) => !isValueClass(sym)
@@ -346,13 +347,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* These are in a meaningful order for stability purposes.
*/
def concreteTypes(sym: Symbol): List[Type] = {
- val types = (
- if (!isSpecialized(sym)) Nil // no @specialized Annotation
- else specializedOn(sym) match {
- case Nil => specializableTypes // specialized on everything
- case args => args map (s => specializesClass(s).tpe) sorted // specialized on args
- }
- )
+ val types = if (!isSpecialized(sym))
+ Nil // no @specialized Annotation
+ else
+ specializedOn(sym) map (s => specializesClass(s).tpe) sorted
+
if (isBoundedGeneric(sym.tpe) && (types contains AnyRefClass))
reporter.warning(sym.pos, sym + " is always a subtype of " + AnyRefClass.tpe + ".")