summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
3 files changed, 16 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
index 8f2b1b9797..086ff74b0e 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
@@ -511,7 +511,13 @@ abstract class CopyPropagation {
/** Drop everything known about mutable record fields.
*
- * @param state ...
+ * A simple escape analysis would help here. Some of the records we
+ * track never leak to other methods, therefore they can not be changed.
+ * We should not drop their bindings in this case. A closure object
+ * would be such an example. Some complications:
+ *
+ * - outer pointers. An closure escapes as an outer pointer to another
+ * nested closure.
*/
final def invalidateRecords(state: copyLattice.State) {
def shouldRetain(sym: Symbol): Boolean = {
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 6292968c7a..7ac989374b 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -188,10 +188,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
private def specializedName(sym: Symbol, env: TypeEnv): Name = {
val tvars = if (sym.isClass) env.keySet
else specializedTypeVars(sym.info).intersect(env.keySet)
- log("specName(" + sym + ") env " + env + " tvars: " + tvars + " stv: " + specializedTypeVars(sym.info) + " info: " + sym.info)
val (methparams, others) = tvars.toList.partition(_.owner.isMethod)
val tvars1 = methparams.sort(_.name.toString < _.name.toString)
val tvars2 = others.sort(_.name.toString < _.name.toString)
+ log("specName(" + sym + ") env " + env)
specializedName(sym.name, tvars1 map env, tvars2 map env)
}
@@ -552,18 +552,21 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
private def normalizeMember(owner: Symbol, sym: Symbol, outerEnv: TypeEnv): List[Symbol] = {
if (sym.isMethod && !sym.info.typeParams.isEmpty) {
val (stps, tps) = splitParams(sym.info.typeParams)
- val res = sym :: (for (env <- specializations(stps)) yield {
+ val res = sym :: (for (env <- specializations(stps) if needsSpecialization(env, sym)) yield {
val keys = env.keys.toList;
val vals = env.values.toList
val specMember = sym.cloneSymbol(owner).setFlag(SPECIALIZED).resetFlag(DEFERRED)
specMember.name = specializedName(sym, env)
+
typeEnv(specMember) = outerEnv ++ env
val tps1 = cloneSymbols(tps)
for (tp <- tps1) tp.setInfo(tp.info.subst(keys, vals))
- val methodType = sym.info.resultType.subst(keys ::: tps, vals ::: (tps1 map (_.tpe)))
+ // the cloneInfo is necessary so that method parameter symbols are cloned at the new owner
+ val methodType = sym.info.resultType.subst(keys ::: tps, vals ::: (tps1 map (_.tpe))).cloneInfo(specMember)
specMember.setInfo(polyType(tps1, methodType))
- log("expanded member: " + sym + " -> " + specMember + ": " + specMember.info + " env: " + env)
+
+ log("expanded member: " + sym + ": " + sym.info + " -> " + specMember + ": " + specMember.info + " env: " + env)
info(specMember) = NormalizedMember(sym)
overloads(sym) = Overload(specMember, env) :: overloads(sym)
specMember
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 0b95590aa3..6268db7024 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1094,6 +1094,8 @@ trait Namers { self: Analyzer =>
}
if (!ainfos.isEmpty)
annotated.setAnnotations(ainfos)
+ if (annotated.isTypeSkolem)
+ annotated.deSkolemize.setAnnotations(ainfos)
case _ =>
}
implicit val scopeKind = TypeSigScopeKind