From 0f4b2306ecf7f2f04d1af5bec12945eb30218154 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Wed, 5 May 2010 17:59:21 +0000 Subject: Tightened what gets specialized: only when the ... Tightened what gets specialized: only when the type parameter appears at top level, or as a type argument to a Java array. For example T, Array[T] cause specialization, but List[T] does not. Resurrected spec-matrix, forgotten among the disabled tests. No review. --- .../tools/nsc/transform/SpecializeTypes.scala | 40 +++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 9215064856..d9c851be79 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -288,21 +288,15 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { else for (v <- values(xs.head); vs <- count(xs.tail, values)) yield v :: vs } - /** Does the given tpe need to be specialized in the environment 'env'? */ + /** Does the given tpe need to be specialized in the environment 'env'? + * Specialization is needed for + * - members with specialized type parameters found in the given environment + * - constructors of specialized classes + * - normalized members whose type bounds appear in the environment + */ private def needsSpecialization(env: TypeEnv, sym: Symbol): Boolean = { - def needsIt(tpe: Type): Boolean = tpe match { - case TypeRef(pre, sym, args) => - (env.keysIterator.contains(sym) - || (args exists needsIt)) - case PolyType(tparams, resTpe) => needsIt(resTpe) - case MethodType(argTpes, resTpe) => - (argTpes exists (sym => needsIt(sym.tpe))) || needsIt(resTpe) - case ClassInfoType(parents, stats, sym) => - stats.toList exists (s => needsIt(s.info)) - case _ => false - } - - (needsIt(sym.info) + (specializedTypeVars(sym).intersect(env.keySet).nonEmpty + || (sym.isClassConstructor && sym.enclClass.typeParams.exists(_.hasAnnotation(SpecializedClass))) || (isNormalizedMember(sym) && info(sym).typeBoundsIn(env))) } @@ -322,19 +316,25 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { def specializedTypeVars(sym: Symbol): immutable.Set[Symbol] = specializedTypeVars(atPhase(currentRun.typerPhase)(sym.info)) - /** Return the set of @specialized type variables mentioned by the given type. */ + /** Return the set of @specialized type variables mentioned by the given type. + * It only counts type variables that appear naked or as arguments to Java + * arrays (the only places where it makes sense to specialize). + */ def specializedTypeVars(tpe: Type): immutable.Set[Symbol] = tpe match { case TypeRef(pre, sym, args) => - if (sym.isTypeParameter && sym.hasAnnotation(SpecializedClass)) - specializedTypeVars(args) + sym - else if (sym.isTypeSkolem && sym.deSkolemize.hasAnnotation(SpecializedClass)) { - specializedTypeVars(args) + sym - } else + if ( sym.isTypeParameter && sym.hasAnnotation(SpecializedClass) + || (sym.isTypeSkolem && sym.deSkolemize.hasAnnotation(SpecializedClass))) + immutable.ListSet.empty + sym + else if (sym == definitions.ArrayClass) specializedTypeVars(args) + else immutable.ListSet.empty[Symbol] + case PolyType(tparams, resTpe) => specializedTypeVars(tparams map (_.info)) ++ specializedTypeVars(resTpe) + case MethodType(argSyms, resTpe) => specializedTypeVars(argSyms map (_.tpe)) ++ specializedTypeVars(resTpe) + case ExistentialType(_, res) => specializedTypeVars(res) case AnnotatedType(_, tp, _) => specializedTypeVars(tp) case TypeBounds(hi, lo) => specializedTypeVars(hi) ++ specializedTypeVars(lo) -- cgit v1.2.3