summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala44
-rw-r--r--src/library/scala/AnyCompanion.scala6
-rw-r--r--src/library/scala/AnyValCompanion.scala3
-rw-r--r--src/library/scala/Ref.scala12
-rw-r--r--src/library/scala/specialized.scala2
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)
}