diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala | 44 | ||||
-rw-r--r-- | src/library/scala/AnyCompanion.scala | 6 | ||||
-rw-r--r-- | src/library/scala/AnyValCompanion.scala | 3 | ||||
-rw-r--r-- | src/library/scala/Ref.scala | 12 | ||||
-rw-r--r-- | src/library/scala/specialized.scala | 2 |
6 files changed, 62 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 1757048036..99367e1de8 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -49,7 +49,8 @@ trait Definitions extends reflect.generic.StandardDefinitions { tpnme.Float -> FLOAT_TAG, tpnme.Double -> DOUBLE_TAG, tpnme.Boolean -> BOOL_TAG, - tpnme.Unit -> VOID_TAG + tpnme.Unit -> VOID_TAG, + tpnme.Object -> CLASS_TAG ) private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f) @@ -58,7 +59,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { private def boxedName(name: Name) = sn.Boxed(name.toTypeName) - lazy val abbrvTag = symbolsMap(ScalaValueClasses, nameToTag) + lazy val abbrvTag = symbolsMap(ObjectClass :: ScalaValueClasses, nameToTag) lazy val numericWeight = symbolsMapFilt(ScalaValueClasses, nameToWeight.keySet, nameToWeight) lazy val boxedModule = classesMap(x => getModule(boxedName(x))) lazy val boxedClass = classesMap(x => getClass(boxedName(x))) @@ -175,6 +176,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { lazy val AnyClass = newClass(ScalaPackageClass, tpnme.Any, Nil) setFlag (ABSTRACT) lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.typeConstructor) lazy val ObjectClass = getClass(sn.Object) + lazy val AnyCompanionClass = getClass("scala.AnyCompanion") setFlag (SEALED | ABSTRACT | TRAIT) lazy val AnyValCompanionClass = getClass("scala.AnyValCompanion") setFlag (SEALED | ABSTRACT | TRAIT) // bottom types @@ -237,7 +239,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { lazy val ConsoleModule: Symbol = getModule("scala.Console") lazy val ScalaRunTimeModule: Symbol = getModule("scala.runtime.ScalaRunTime") lazy val SymbolModule: Symbol = getModule("scala.Symbol") - lazy val Symbol_apply = getMember(SymbolModule, nme.apply) + lazy val Symbol_apply = getMember(SymbolModule, nme.apply) def SeqFactory = getMember(ScalaRunTimeModule, nme.Seq) def arrayApplyMethod = getMember(ScalaRunTimeModule, "array_apply") def arrayUpdateMethod = getMember(ScalaRunTimeModule, "array_update") @@ -246,6 +248,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { def ensureAccessibleMethod = getMember(ScalaRunTimeModule, "ensureAccessible") def scalaRuntimeHash = getMember(ScalaRunTimeModule, "hash") def scalaRuntimeSameElements = getMember(ScalaRunTimeModule, nme.sameElements) + lazy val RefModule = getModule("scala.Ref") // classes with special meanings lazy val NotNullClass = getClass("scala.NotNull") diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index bd8d9db27e..db951c9111 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -29,7 +29,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { import definitions.{ RootClass, BooleanClass, UnitClass, ArrayClass, ScalaValueClasses, - SpecializedClass, RepeatedParamClass, JavaRepeatedParamClass + SpecializedClass, RepeatedParamClass, JavaRepeatedParamClass, + AnyRefClass, RefModule, ObjectClass } private def isSpecialized(sym: Symbol) = sym hasAnnotation SpecializedClass @@ -232,17 +233,24 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { nme.getterToLocal(specializedName(nme.localToGetter(name), types1, types2)) else { val (base, cs, ms) = nme.splitSpecializedName(name) + val abbrevs = definitions.abbrvTag withDefaultValue definitions.abbrvTag(ObjectClass) newTermName(base.toString + "$" - + "m" + ms + types1.map(t => definitions.abbrvTag(t.typeSymbol)).mkString("", "", "") - + "c" + cs + types2.map(t => definitions.abbrvTag(t.typeSymbol)).mkString("", "", "$sp")) + + "m" + ms + types1.map(t => abbrevs(t.typeSymbol)).mkString("", "", "") + + "c" + cs + types2.map(t => abbrevs(t.typeSymbol)).mkString("", "", "$sp")) } } lazy val primitiveTypes = ScalaValueClasses map (_.tpe) + private def tParamSubAnyRef(sym: Symbol) = { + val tparam = sym.owner.newTypeParameter(sym.pos, sym.name.asInstanceOf[TypeName]) + .setInfo(TypeBounds.upper(AnyRefClass.tpe)) + tparam.tpe + } + /** Return the concrete types `sym' should be specialized at. */ - def concreteTypes(sym: Symbol): List[Type] = + def concreteTypes(sym: Symbol): List[Type] = { sym.getAnnotation(SpecializedClass) match { case Some(AnnotationInfo(_, args, _)) => args match { @@ -250,13 +258,16 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { log(sym + " specialized on everything") primitiveTypes case _ => - val tpes = args.map(_.symbol.companionClass.tpe) + val tpes = args map { + t => if (t.symbol == RefModule) tParamSubAnyRef(sym) else t.symbol.companionClass.tpe + } log(sym + " specialized on " + tpes) tpes } case _ => Nil } + } /** Return a list of all type environments for all specializations * of @specialized types in `tps'. @@ -338,6 +349,17 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case _ => immutable.ListSet.empty[Symbol] } + def isPrimitive(tpe: Type) = definitions.ScalaValueClasses contains tpe.typeSymbol + + def survivingParams(params: List[Symbol], env: TypeEnv) = + params.filter(p => !isSpecialized(p) || !isPrimitive(env(p))) + + def cloneAndRemoveAnnotation(syms: List[Symbol], owner: Symbol) = { + val cloned = cloneSymbols(syms, owner) + cloned foreach { _.removeAnnotation(SpecializedClass) } + cloned + } + /** Specialize 'clazz', in the environment `outerEnv`. The outer * environment contains bindings for specialized types of enclosing * classes. @@ -369,12 +391,15 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // has to be a val in order to be computed early. It is later called // within 'atPhase(next)', which would lead to an infinite cycle otherwise val specializedInfoType: Type = { - val (_, unspecParams) = splitParams(clazz.info.typeParams) - oldClassTParams = unspecParams - newClassTParams = cloneSymbols(unspecParams, cls) map subst(env) + // val (_, unspecParams) = splitParams(clazz.info.typeParams) + // oldClassTParams = unspecParams + val survivedParams = survivingParams(clazz.info.typeParams, env) + oldClassTParams = survivedParams + newClassTParams = cloneAndRemoveAnnotation(survivedParams, cls) map subst(env) + log("new tparams " + newClassTParams.zip(newClassTParams map {_.tpe})) def applyContext(tpe: Type) = - subst(env, tpe).subst(unspecParams, newClassTParams map (_.tpe)) + subst(env, tpe).subst(survivedParams, newClassTParams map (_.tpe)) /** Return a list of specialized parents to be re-mixed in a specialized subclass. * Assuming env = [T -> Int] and @@ -586,6 +611,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { }) var hasSubclasses = false + log("For " + clazz + " - " + specializations(clazz.info.typeParams)) for (env <- specializations(clazz.info.typeParams) if satisfiable(env)) { val spc = specializedClass(env, decls1) log("entered " + spc + " in " + clazz.owner) diff --git a/src/library/scala/AnyCompanion.scala b/src/library/scala/AnyCompanion.scala new file mode 100644 index 0000000000..0a14ebacdb --- /dev/null +++ b/src/library/scala/AnyCompanion.scala @@ -0,0 +1,6 @@ +package scala + + + + +private[scala] trait AnyCompanion { } diff --git a/src/library/scala/AnyValCompanion.scala b/src/library/scala/AnyValCompanion.scala index 854a63e865..3c3379de38 100644 --- a/src/library/scala/AnyValCompanion.scala +++ b/src/library/scala/AnyValCompanion.scala @@ -1,3 +1,4 @@ + /* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** @@ -18,4 +19,4 @@ package scala * }}} * */ -private[scala] trait AnyValCompanion { } +private[scala] trait AnyValCompanion extends AnyCompanion { } diff --git a/src/library/scala/Ref.scala b/src/library/scala/Ref.scala new file mode 100644 index 0000000000..327b4a91f1 --- /dev/null +++ b/src/library/scala/Ref.scala @@ -0,0 +1,12 @@ +package scala + + + + + + +object Ref extends AnyCompanion + + + + diff --git a/src/library/scala/specialized.scala b/src/library/scala/specialized.scala index 656508c9d9..38ad8c4c9a 100644 --- a/src/library/scala/specialized.scala +++ b/src/library/scala/specialized.scala @@ -25,7 +25,7 @@ package scala * * @since 2.8 */ -class specialized(types: AnyValCompanion*) extends annotation.StaticAnnotation { +class specialized(types: AnyCompanion*) extends annotation.StaticAnnotation { def this() { this(Unit, Boolean, Byte, Short, Char, Int, Long, Float, Double) } |