summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-02-18 22:55:34 -0800
committerPaul Phillips <paulp@improving.org>2012-02-18 23:48:26 -0800
commitec160bae7e2935d98bf71cfb6dcba61f1979b854 (patch)
tree11ed857d21aaac691481e12eabfc53a4446065d4 /src
parent0d19fe04eb43d39bdceab570fb5400a3a4b072ea (diff)
downloadscala-ec160bae7e2935d98bf71cfb6dcba61f1979b854.tar.gz
scala-ec160bae7e2935d98bf71cfb6dcba61f1979b854.tar.bz2
scala-ec160bae7e2935d98bf71cfb6dcba61f1979b854.zip
More on SI-5500.
A reimagining of erik's patch in 1df4fc6e59 . He did the hard part, this is the batman reboot. I added more tests and tried to make the anyref caching code less fragile.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/NameManglers.scala14
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala22
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala38
4 files changed, 41 insertions, 34 deletions
diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala
index 97a74c2383..c4ee7254dc 100644
--- a/src/compiler/scala/reflect/internal/NameManglers.scala
+++ b/src/compiler/scala/reflect/internal/NameManglers.scala
@@ -76,12 +76,14 @@ trait NameManglers {
val PROTECTED_PREFIX = "protected$"
val PROTECTED_SET_PREFIX = PROTECTED_PREFIX + "set"
val SINGLETON_SUFFIX = ".type"
- val SPECIALIZED_SUFFIX_STRING = "$sp"
val SUPER_PREFIX_STRING = "super$"
val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$"
+ val SETTER_SUFFIX: TermName = encode("_=")
- val SETTER_SUFFIX: TermName = encode("_=")
- val SPECIALIZED_SUFFIX_NAME: TermName = SPECIALIZED_SUFFIX_STRING
+ @deprecated("2.10.0", "Use SPECIALIZED_SUFFIX")
+ def SPECIALIZED_SUFFIX_STRING = SPECIALIZED_SUFFIX.toString
+ @deprecated("2.10.0", "Use SPECIALIZED_SUFFIX")
+ def SPECIALIZED_SUFFIX_NAME: TermName = SPECIALIZED_SUFFIX.toTermName
def isConstructorName(name: Name) = name == CONSTRUCTOR || name == MIXIN_CONSTRUCTOR
def isExceptionResultName(name: Name) = name startsWith EXCEPTION_RESULT_PREFIX
@@ -120,7 +122,7 @@ trait NameManglers {
}
def unspecializedName(name: Name): Name = (
- if (name endsWith SPECIALIZED_SUFFIX_NAME)
+ if (name endsWith SPECIALIZED_SUFFIX)
name.subName(0, name.lastIndexOf('m') - 1)
else name
)
@@ -140,8 +142,8 @@ trait NameManglers {
* and another one belonging to the enclosing class, on Double.
*/
def splitSpecializedName(name: Name): (Name, String, String) =
- if (name endsWith SPECIALIZED_SUFFIX_NAME) {
- val name1 = name dropRight SPECIALIZED_SUFFIX_NAME.length
+ if (name endsWith SPECIALIZED_SUFFIX) {
+ val name1 = name dropRight SPECIALIZED_SUFFIX.length
val idxC = name1 lastIndexOf 'c'
val idxM = name1 lastIndexOf 'm'
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index b4c404a80c..f61fe7a457 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -99,6 +99,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val MODULE_VAR_SUFFIX: NameType = "$module"
val ROOT: NameType = "<root>"
val PACKAGE: NameType = "package"
+ val SPECIALIZED_SUFFIX: NameType = "$sp"
// value types (and AnyRef) are all used as terms as well
// as (at least) arguments to the @specialize annotation.
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index b3ff2c6329..8e9788e8b6 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -1383,15 +1383,25 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
cloneSymbol(owner)
/** A clone of this symbol, but with given owner. */
- final def cloneSymbol(owner: Symbol): Symbol = cloneSymbol(owner, this.rawflags)
- final def cloneSymbol(owner: Symbol, newFlags: Long): Symbol = {
- val newSym = cloneSymbolImpl(owner, newFlags)
- ( newSym
+ final def cloneSymbol(newOwner: Symbol): Symbol =
+ cloneSymbol(newOwner, this.rawflags)
+ final def cloneSymbol(newOwner: Symbol, newFlags: Long): Symbol =
+ cloneSymbol(newOwner, newFlags, nme.NO_NAME)
+ final def cloneSymbol(newOwner: Symbol, newFlags: Long, newName: Name): Symbol = {
+ val clone = cloneSymbolImpl(newOwner, newFlags)
+ ( clone
setPrivateWithin privateWithin
- setInfo (info cloneInfo newSym)
+ setInfo (this.info cloneInfo clone)
setAnnotations this.annotations
)
+ if (clone.thisSym != clone)
+ clone.typeOfThis = (clone.typeOfThis cloneInfo clone)
+ if (newName != nme.NO_NAME)
+ clone.name = newName
+
+ clone
}
+
/** Internal method to clone a symbol's implementation with the given flags and no info. */
def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol
def cloneSymbolImpl(owner: Symbol): Symbol = cloneSymbolImpl(owner, 0L)
@@ -2327,7 +2337,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def existentialBound: Type = abort("unexpected type: "+this.getClass+ " "+debugLocationString)
- override def name: TypeName = super.name.asInstanceOf[TypeName]
+ override def name: TypeName = super.name.toTypeName
final override def isType = true
override def isNonClassType = true
override def isAbstractType = {
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 468518d938..3254844344 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -87,10 +87,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Map class symbols to the type environments where they were created. */
private val typeEnv = mutable.HashMap[Symbol, TypeEnv]() withDefaultValue emptyEnv
- // holds mappings from regular type parameter symbols and their class to
- // symbols of specialized type parameters which are subtypes of AnyRef
- // e.g. (sym, clazz) => specializedSym
- private val anyrefSpecCache = perRunCaches.newMap[(Symbol, Symbol), Symbol]()
+ // Key: a specialized class or method
+ // Value: a map from tparams in the original class to tparams in the specialized class.
+ private val anyrefSpecCache = perRunCaches.newMap[Symbol, mutable.Map[Symbol, Symbol]]()
// holds mappings from members to the type variables in the class
// that they were already specialized for, so that they don't get
@@ -432,29 +431,24 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case _ => Set()
}
- /** Returns the type parameter in the specialized class `clazz` that corresponds to type parameter
- * `sym` in the original class. It will create it if needed or use the one from the cache.
+ /** Returns the type parameter in the specialized class `sClass` that corresponds to type parameter
+ * `tparam` in the original class. It will create it if needed or use the one from the cache.
*/
- private def typeParamSubAnyRef(sym: Symbol, clazz: Symbol) = (
- anyrefSpecCache.getOrElseUpdate((sym, clazz),
- clazz.newTypeParameter(sym.name append nme.SPECIALIZED_SUFFIX_NAME toTypeName, sym.pos)
- setInfo TypeBounds(sym.info.bounds.lo, AnyRefClass.tpe)
+ private def typeParamSubAnyRef(tparam: Symbol, sClass: Symbol): Type = {
+ val sClassMap = anyrefSpecCache.getOrElseUpdate(sClass, mutable.Map[Symbol, Symbol]())
+
+ sClassMap.getOrElseUpdate(tparam,
+ tparam.cloneSymbol(sClass, tparam.flags, tparam.name append tpnme.SPECIALIZED_SUFFIX)
+ modifyInfo (info => TypeBounds(info.bounds.lo, AnyRefClass.tpe))
).tpe
- )
+ }
/** Cleans the anyrefSpecCache of all type parameter symbols of a class.
*/
- private def cleanAnyRefSpecCache(clazz: Symbol, decls: List[Symbol]) = (
+ private def cleanAnyRefSpecCache(clazz: Symbol, decls: List[Symbol]) {
// remove class type parameters and those of normalized members.
- clazz :: decls foreach {
- _.tpe match {
- case PolyType(tparams, _) => tparams.foreach {
- s => anyrefSpecCache.remove((s, clazz))
- }
- case _ => ()
- }
- }
- )
+ clazz :: decls foreach (anyrefSpecCache remove _)
+ }
/** Type parameters that survive when specializing in the specified environment. */
def survivingParams(params: List[Symbol], env: TypeEnv) =
@@ -1710,7 +1704,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* - there is a getter for the specialized field in the same class
*/
def initializesSpecializedField(f: Symbol) = (
- (f.name endsWith nme.SPECIALIZED_SUFFIX_NAME)
+ (f.name endsWith nme.SPECIALIZED_SUFFIX)
&& clazz.info.member(nme.originalName(f.name)).isPublic
&& clazz.info.decl(f.name).suchThat(_.isGetter) != NoSymbol
)