diff options
author | Erik Osheim <d_m@plastic-idolatry.com> | 2012-02-19 10:25:03 -0500 |
---|---|---|
committer | Erik Osheim <d_m@plastic-idolatry.com> | 2012-02-19 11:20:58 -0500 |
commit | cf0ae72aae43dae1e47489fceb684e5448080736 (patch) | |
tree | bc087d70ea864ca8d6a91d6367dcf89c0eb77bb0 /src/compiler | |
parent | 4a5c6a01840404edd362bd388e39f68cb6af5dc7 (diff) | |
download | scala-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')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala | 31 |
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 + ".") |