summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-10-08 23:50:59 +1000
committerJason Zaugg <jzaugg@gmail.com>2014-10-09 00:28:12 +1000
commit24a0777219d647ec310a0b6da305f619f69950cd (patch)
tree1a1e02b629a6f15dceeaf8186ea837831270d032 /src
parent8d25e84c9123fe9784ec9844b5184aa1b697b429 (diff)
downloadscala-24a0777219d647ec310a0b6da305f619f69950cd.tar.gz
scala-24a0777219d647ec310a0b6da305f619f69950cd.tar.bz2
scala-24a0777219d647ec310a0b6da305f619f69950cd.zip
SI-8871 Fix specialization under REPL / FSC
The transformation of applications to specialized methods relies on the owner of said method having had the specialization info transform run which stashes a bunch of related data into per-run caches such as `SpecializeTypes#{typeEnv}`. Recently, we found that per-run caches didn't quite live up to there name, and in fact weren't being cleaned up before a new run. This was remedied in 00e11ff. However, no good deed goes unpunished, and this led to a regression in specialization in the REPL and FSC. This commit makes two changes: - change the specialization info tranformer to no longer directly enter specialized methods into the `info` of whatever the current phase happens to be. This stops them showing up `enteringTyper` of the following run. - change `adaptInfos` to simply discard all but the oldest entry in the type history when bringing a symbol from one run into the next. This generalizes the approach taken to fix SI-7801. The specialization info transformer will now execute in each run, and repopulate `typeEnv` and friends. I see that we have a seemingly related bandaid for this sort of problem since 08505bd4ec. In a followup, I'll try to revert that.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala5
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala13
2 files changed, 5 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 908aa69310..f56739b811 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -861,11 +861,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
debuglog("%s expands to %s in %s".format(sym, specMember.name.decode, pp(env)))
info(specMember) = NormalizedMember(sym)
newOverload(sym, specMember, env)
- // if this is a class, we insert the normalized member in scope,
- // if this is a method, there's no attached scope for it (EmptyScope)
- val decls = owner.info.decls
- if (decls != EmptyScope)
- decls.enter(specMember)
specMember
}
}
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index b0c23ef45d..3296b2322f 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -173,7 +173,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
with HasFlags
with Annotatable[Symbol]
with Attachable {
-
// makes sure that all symbols that runtime reflection deals with are synchronized
private def isSynchronized = this.isInstanceOf[scala.reflect.runtime.SynchronizedSymbols#SynchronizedSymbol]
private def isAprioriThreadsafe = isThreadsafe(AllOps)
@@ -1592,13 +1591,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
assert(isCompilerUniverse)
if (infos == null || runId(infos.validFrom) == currentRunId) {
infos
- } else if (isPackageClass) {
- // SI-7801 early phase package scopes are mutated in new runs (Namers#enterPackage), so we have to
- // discard transformed infos, rather than just marking them as from this run.
- val oldest = infos.oldest
- oldest.validFrom = validTo
- this.infos = oldest
- oldest
+ } else if (infos ne infos.oldest) {
+ // SI-8871 Discard all but the first element of type history. Specialization only works in the resident
+ // compiler / REPL if re-run its info transformer in this run to correctly populate its
+ // per-run caches, e.g. typeEnv
+ adaptInfos(infos.oldest)
} else {
val prev1 = adaptInfos(infos.prev)
if (prev1 ne infos.prev) prev1