From 1df4fc6e59e65b202d98486ca698c721122054d2 Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Sun, 19 Feb 2012 00:09:36 -0500 Subject: Fixed over-optimistic anyrefSpecCache (closes SI-5500). The basic problem here was that generic type params were getting confused between the various specialized subclasses. For instance, calling typeParamsSubAnyRef(A, C2$mcLI$sp) might return the wrong specialized type param, e.g. C2$mcLZ$sp.A$sp (note the Z instead of the I). The fix is to cache with both the sym (A) and also the clazz (C2$mcLI$sp). This may resolve a whole host of other obscure AnyRef specialization problems. --- .../scala/tools/nsc/transform/SpecializeTypes.scala | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 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 8b1d5b3295..d96dff26db 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -87,9 +87,10 @@ 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 to symbols of - // specialized type parameters which are subtypes of AnyRef - private val anyrefSpecCache = perRunCaches.newMap[Symbol, Symbol]() + // 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]() // holds mappings from members to the type variables in the class // that they were already specialized for, so that they don't get @@ -435,7 +436,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * `sym` 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, + anyrefSpecCache.getOrElseUpdate((sym, clazz), clazz.newTypeParameter(sym.name append nme.SPECIALIZED_SUFFIX_NAME toTypeName, sym.pos) setInfo TypeBounds(sym.info.bounds.lo, AnyRefClass.tpe) ).tpe @@ -447,8 +448,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // remove class type parameters and those of normalized members. clazz :: decls foreach { _.tpe match { - case PolyType(tparams, _) => anyrefSpecCache --= tparams - case _ => () + case PolyType(tparams, _) => tparams.foreach { + s => anyrefSpecCache.remove((s, clazz)) + } + case _ => () } } ) -- cgit v1.2.3